ExpressJS: Retrieving images from MongoDB and displaying them in Jade - image

I am looking for good ways to retrieve images from MongoDB and display them. For example, to retrieve a profile picture and display it on a profile page, this is how I am currently doing it:
profile page
block content
h1= session.user.name
img(src='/avatars')
routes
exports.avatars = (req, res) ->
users.find req.session.user, (err, user) ->
if user
res.writeHead('200', {'Content-Type': 'image/png'})
res.end(user.avatar.data, 'binary')
else
res.locals.flash = err
res.render('index', {title: 'Home'})
Basically I render the profile page, and the img tag sends a request back to the server to pick up the picture of the user from the database. Im saving the images as BinData in MongoDB. Not using GridFS because I expect the pictures to be small.
Is there a better way to do this?? I tried to send the image data directly to the jade view using res.render('users/show', {picture: data}) but the img tag didn't like that and I'm not clear on why. Is this approach a dead end?
Any comments/suggestions would be much appreciated. Thanks!

Sending the image data directly to jade view would work if
a) you base64 encoded the image data
b) prefixed with "data:"
But I would not recommend you do this way, you essentially in-lining the image in your html.
You should instead create a separate route to handle your images/avatars.
For example the image source for your avatars should be something like
img(src='http://mydomain.com/avatars/user1.jpg')
When the browser requests this image you then respond with image data retrieved from mongo.

Related

Returning an image response from storage along with other data?

In a controller I return a view with data. Along with this data, how can I also send back an image?
The image needs to be loaded via Storage as it's private, I get the image and build an image response in a class.
How can I also return this image response along side my data?
I've tried setting the response to a var in my data and displaying that in img src but it fails to load the image.
Normally I work with url. Storage::url('file.ext') give you a lot of possibility. There is also a way to create temporary url with this method within the Storage facade $url = Storage::temporaryUrl('file.jpg', now()->addMinutes(5)); You have to indicate when the url should expire.
There is another method that I use with drawboard.
You first have to get the content of your image. I don't remember, but I think the get() method of storage do the job. Maybe it's a bit more complex.
Whatever, you have to get the raw data of the image, put it into a variable and send it to the view.
Then, in the src of the image, you do this:
<img src="data:image/png;base64, {{$varToRawData}}" />
Be sure to use the right image/extension

Submitting data after image upload

My site has a feature that allows users to create posts (like Facebook). I have a form with a "Message" input field and a button that allows users to upload images.
Right now, how I have the code set up is that when the user submits the form, my code will submit the data first, and then upload the images.
The problem with this is that if the user cancels the image upload half way through, the database record will exist (because the data was submitted before the image upload), but there will be no images uploaded.
So my solution to this is to upload the images first and submit the data after. The problem with this is that I'm not sure how I can tie the images to the data in a database record.
Should I upload all of the images to /tmp and then move the files to a permanent directory, like /var/www/html/website/public/img/uploads/<upload_id> where upload_id is the id of the database record?
What should I do if the user uploads an image, but closes the tab half way. Then there will be an image in /tmp that will stay there forever unless the directory is cleaned up. How would I clean it up?
Is this the best way to do this or are there better ways?
I'm using Laravel 5.3 and Dropzone.js.
Thanks.
Since you are using Dropzone.js which allows files to be uploaded via ajax, you can do this the following way :
1) Send file to the backend server using Dropzone.js (ajax).
2) Since you are using laravel, each file you receive will be an instance of UploadedFile, you can use this class to access the Original Name of the file uploaded, size, MimeType etc.
3) In the Image Model in your database (create this if not done already), create a new record for this image and store the fields mentioned above if needed, along with the path where you will be storing the image. You can use this path stored in the table row to access the image later.
4) Get the 'id' of the newly inserted row in the Image Table and pass it back to the frontend where you can receive it using the 'success' event Handler for the Dropzone plugin.
5) Append this newly inserted 'id' as a hidden input element in your form.
6) When you submit the form, you will receive the image ids related to your post and you may save it using the Database relationship of your choice.
7) Yes, you need an additional check for images that have been uploaded and entered in your Image table, but those whose posts have not been created. You may create an Artisan CLI command for the same and assign it as a Cron Job.
I think you should submit your form with AJAX. This solution was useful for me.
Make a, span or other element with event "onclick" instead of button, because button pressing will confirm the form automatically, even if the button's type isn't a "submit".
Write an ajax function like this:
function newsFormSubmit(item_id){
var formData = new FormData($('.news-form')[0]);
formData.append("item_id", item_id);
$.ajax({
type: 'POST',
url: config.routes[0].savenews,
data: formData,
processData: false,
contentType: false,
success: function (data) {
if (data.error)
{
alert(data.error);
return false;
} else if (data)
{
$('#news-card-' + item_id).html(data);
}
}
});
}
Place this function on onclick event.

How to retrieve images (decoded if possible) present in a wepage using XPCOM

How to get all the images, after decoding if possible, on a webpage through XPCOM ?
The image might be specified in HTML as a background url in some CSS property, inside img tag, or in any form that a web developer might have included.
I tried looking into imgIContainer, imgIDecodeObserver and many other interfaces. Although there is a way through which we can provide image URI to Mozilla so that it loads the image, decodes it and returns imgIContainer. But I couldn't find anyway to get all images in current webpage.
This has to be done in either Java or Javascript.
Any suggestions?
#Wladimir - Thanks for your help.
I want all the images including CSS constructs (background images). So now I am listening to events from nsIWebProgressListener.
onStateChange: function(webProgress, request, stateFlags, status) {
if ((~stateFlags & (nsIWebProgressListener.STATE_IS_REQUEST | nsIWebProgressListener.STATE_STOP)) == 0) {
var imgReq = request.QueryInterface(CI.imgIRequest);
if (imgReq)
var img = imgReq.image;
}
}
The problem is that request.QueryInterface(CI.imgIRequest) throws exception for all NON-image requests. Although those exceptions can be ignored by putting code inside try-catch block, but I'd prefer to do things cleanly.
Is there any condition that can be checked to know whether request is for image or not?
There is existing code that you can look at. The Page Info dialog has a Media tab that successfully shows most images on the page. The important function is grabAll() in pageInfo.js, it is called for each element (via a TreeWalker). As you can see, there is no generic way to get the image, this function rather uses window.getComputedStyle() to extract the values of a bunch of the CSS properties for this element: background-image, border-image, list-style-image, cursor. It will also look for <img>, <svg:image>, <link> (favicon), <input>, <button>, <object> and <embed> tags. It doesn't manage to recognize everything however, e.g. these CSS constructs will not be recognized:
.foo:before
{
content: url(image.png);
}
.foo:hover
{
background-image: url(image.png);
}
Still, this is probably as far as you can get - unless you want to look at the requests made by the web page as it loads.
Edit: If you look at the requests as they are performed (via a web progress listener), you can do the following:
if (request instanceof CI.imgIRequest)
var img = request.URI.spec;
Note that request.image won't help you much, almost all methods of imgIContainer are only accessible from native code.

Uploading single image and showing its thumbnail using jquery and asp.net mvc3

I need to upload the photo of a user with his details from asp.net mvc3 razor view. The image selected by the user has to be shown as thumbnail before submitting the form.
The model of the view contains a byte array property called Photo. On page load i am converting this byte array to base 64 string and showing it in . this is working properly .
Now i need to show the thumbnail of the image selected by the user. And when he clicks on submit button i need to bind the selected image to the model property Photo.
After googling , i came to know that showing thumbnail is not possible until I upload that image. I tried Uploadify but its UI behavior is not what i am expecting. I also tried the article http://www.dustinhorne.com/post/2011/11/16/AJAX-File-Uploads-with-jQuery-and-MVC-3.aspx, but it is also not suitable in our scenario.
can anyone help me by sharing their experience achieving this scenario.
Thanks in advance.
You could achieve this using HTML5 File API. Take a look at the following article and more specifically the Showing thumbnails of user-selected images section which illustrates an example of how you could achieve that without uploading the image to the server.
And if you want to support legacy browsers that do not yet support the HTML5 File API you could use the jQuery.form plugin which allows you to easily send the contents of a given form to the server using AJAX and it also supports file uploads. So basically you could subscribe to the .change() event of the file input or the .click() event of some see thumbnail ... button and then submit the form to a controller action using AJAX:
$('#myform').ajaxSubmit({
url: '#Url.Action("thumbnail")',
success: function(result) {
// the result variable will contain the result of
// the execution of the Thumbnail action.
// could be a BASE64 encoded representation of
// the thumbnail you generated on the server and then
// simply set it to the src property of your preview `<img>`
// element using the Data Uri scheme
}
});

Dynamically serving images from Google App engine

having problems serving an image stored as a blob from google app engine - I'm trying to view a stored image with the following code
my datastore model is:
class QuestionTemp(db.Model):
picture = db.BlobProperty()
my post call from the initial form is:
class QuestionAsker3(webapp.RequestHandler):
def post(self):
upload_files = self.request.get('file') # 'file' is file upload
tempQuestion = QuestionTemp(picture= db.Blob(upload_files))
tempQuestion.put()
self.response.headers['Content-Type'] = "image/jpeg"
self.response.out.write(tempQuestion.picture)
The image is stored in the blobstore as I can view it in the GAE admin console
"blob viewer".
In chrome the return screen in blank - firefox I get a url and what looks to be a hashcode.
many thanks in advance.
managed to solve the problem - was reading the data into the Blobstore, rather than as a Blob
so the Blob was just storing a references hence had no image data. The .value thing didn't work for me.
Thanks for helping me figure it out #abdul and #adam

Resources