Resize an image before uploading it to firebase - firebase

Firebase storage looks very cool and easy to use, but I'm wondering if there's a way to resize an image before uploading it to Firebase Storage, e.g., run a proccess using ImageMagick in a server and then run the uploading process using Firebase SDK but I notice there aren't storage functions for Firebase SDK Server.

You can also use Firebase Storage + Google Cloud Functions to upload an image, resize the image (using ImageMagick or similar), and write it back to Firebase Storage.
I have an example using these together here (though I trigger the Cloud Vision API, rather than an image resizer).
A quick side note: Firebase Storage doesn't have a Node.js client, instead we recommend using the GCloud-Node library.

Resize using JavaScript Client-Side-Processing
We're using JavaScript resizing, which uses clients device processing power to resize the image, and works GREAT, saving us space and money, saving the netwrok unnecesary bandwidth, and saving the client a bunch of time and also money in most mobile cases.
The original script we are using came from here, and the procedure to use it is as simple as this:
<input type="file" id="select">
<img id="preview">
<script>
document.getElementById('select').onchange = function(evt) {
ImageTools.resize(this.files[0], {
width: 320, // maximum width
height: 240 // maximum height
}, function(blob, didItResize) {
// didItResize will be true if it managed to resize it, otherwise false (and will return the original file as 'blob')
document.getElementById('preview').src = window.URL.createObjectURL(blob);
// you can also now upload this blob using an XHR.
});
};
</script>
I believe that guy (dcollien) deserves a LOT of merit, so I would recommend you to vote his answer up.

You could also use Firebase Storage + the official Firebase Resize Image extension:
https://firebase.google.com/products/extensions/firebase-storage-resize-images. The downside here is that "To install an extension, your project must be on the Blaze (pay as you go) plan". Bc basically what it will do is spin up a Firebase Function App for you, and it'll get triggered every time you upload a file to the path you specify. You can configure things like the desired size as well as the format or if you want to keep a copy of the original file or not. Good thing you won't need to worry about the underlying implementation.

Related

How to get image width/height in next.js?

In my app I allow users to upload their images. Upon uploading it goes into public folder, and in database there is only a direct link for future requests.
When displaying these images on the page I encounter a problem. Image component wants to know height and width of each image. And so I want to know it too.
What are the available options for the workflow in this situation? Both processing while uploading and while requesting will work for me.
You can use image-size npm module:
npm install image-size --save
then:
var sizeOf = require('image-size');
var dimensions = sizeOf('./sample.jpg');
console.log(dimensions.width, dimensions.height);
from: How to check an image dimensions using js or node

Firebase cloud function image resize

Following the example here https://github.com/firebase/functions-samples/blob/master/generate-thumbnail/functions/index.js
How do I notify the client when the image is processed?
I want to have a form upload a photo and resize it to multiple sizes. How do I let the client know when the the cloud function is finished?
I'm using firebase/storage to upload the image client side, then I have a could function listening for files to be uploaded functions.storage.object().onFinalize and processing/resize the images. Is there a callback to the client when the cloud function is finished or to I need to setup pub/sub?
Your ultimate new images (the small ones - or whatever they are), would have some URL, let's say storageCompany.net/123123123123.jpg
So in your realtime Firebase, you will have some location that gives these URLs.
So maybe something like ..
user/NNNN/photos/thumbnails
so to be clear, you might have
user/NNNN/photos/thumbnails/726376733677.jpg
user/NNNN/photos/thumbnails/808080188180.jpg
user/NNNN/photos/thumbnails/363636636636.jpg
and now you're adding
user/NNNN/photos/thumbnails/123123123123.jpg
So indeed, your apps would simply watch for new items (ie, strings - the URLs) appearing in that location!
Just to be clear, let's say you have an ios or droid app that shows "any sort of images", and this is a Firebase project.
So, in your example is "thumbnail images" which are "created by a server".
But it just doesn't matter what sort of images you are showing.
In a
Firebase project, which
"Shows images"
The basic idea is simply what I explain above - you just have, one way or another, a Firebase location which has "the URLs of the images"
It's that simple!
Once the image is "ready" - no matter how that happens - upload, image being generated by 3D software .. whatever ..
That's how you make a Firebase project "with images". iOS, droid or www.
Of course there are many variations. In this example ..
we have a big folder with many "images". each "image" has many fields, including various actual image URLs (thumbnails, big thumbnails, videos, etc etc)
Precisely as you ask, the "thumbnail" (say) URL only appears when that image has been created and upload to some storage URL!
Enjoy
You will have to arrange for an exchange point between the client and your function. Typically, that will be some known location in the database where the function will write the result, and the client can listen for changes to know when the work is complete.
The example you're using will need to be modified to allow the client and server to agree on a unique location ahead of time.
There are two problems with Firebase image resizing - (1) it's tricky to notify the client once the image resizing is complete, and (2) you never know which exact size the client-side app may need (assuming you're building a responsive app).
These two issues can be solved by using a dynamic image resizing approach. The client app can upload images directly to Google Storage (via signed URLs and PUT requests), once the upload is complete it can request the resized image(s) right away. For example:
https://i.kriasoft.com/sample.jpg - original image
https://i.kriasoft.com/w_200,h_100/sample.jpg - dynamically resized image
The resized images can be cached in both the Google Storage bucket and at CDN.
$ npm install image-resizing --save
const { createHandler } = require("image-resizing");
module.exports.img = createHandler({
// Where the source images are located.
// E.g. gs://s.example.com/image.jpg
sourceBucket: "s.example.com",
// Where the transformed images need to be stored.
// E.g. gs://c.example.com/w_80,h_60/image.jpg
cacheBucket: "c.example.com",
});
https://github.com/kriasoft/image-resizing

How to access newly created thumbnail image in Firebase storage from the database?

After using firebase functions and resizing an image in storage, I have a new image with something like "thum_" attached to the name for the new image.
I'm confused how to replace the original image's download url in database with this resized image so that users would load the resized version. If I don't change the name then I assume my function will be stuck in a loop of resizing because it is "thub_" prefix that prevents the function to go through another time as shown here:
....
//****USING THIS TO MAKE SURE FUNCTION DOESN'T GET INTO A LOOP
if (fileName.startsWith('thumb_')) {
console.log('Already a Thumbnail; exit.');
return;
}
....
I am following this sample.
How can I achieve this?
You don't need to overwrite the original, it's okay for the Cloud Functions to save a new image called thumb_.
Once you save the image Cloud Functions will attempt to process the resized image, come across that if statement if (fileName.startsWith('thumb_')) { and exit.

The best way to store and serve up user profile images

My website has public-facing profiles. Users may have 145x145 profile images that are displayed to people. At the moment, I store profile images under a directory on my server: /images/users/ I then use a .ashx file to serve the right image up for each page:
<!-- from the html -->
<img id="imgLogo" runat="server" alt="Company Logo" src="" />
// from the page code behind Page_Load event
imgLogo.Src = "userImage.ashx?id=" + UserId;
// from the .ashx file
String imagePath = context.Server.MapPath("~/images/users/")+context.Request.QueryString["id"]+".jpg";
This code was in place when I joined the project (the guy who wrote it has since left.) It seems to work nicely enough, but I'm new to web development, and unfamiliar with other ways of implementing systems like this.
I now need to add a different kind of image to the site - something like a tall banner ad for a user's profile. As such, these images will be much larger than the 145x145 profile avatars.
How should I implement these for my site? Should I use a similar system to the one currently in place, with images stored in /images/users/largeImage and the src being set to a largeUserImage.ashx file? Or should I store the images in my sql database?
It's likely that I'll want to add more user-defined images in the future - maybe stuff like user photo collections and similar. Is there anything I should consider to make a system that is easily scaleable?
As 3rd party framework like Gravatar doesn't work for your case, you have to do it on your own.
Don't save photos in SQL database, save its paths (image paths of different size) instead. In your userImage.ashx, you can pass 1 more parameter to tell the script which size of image should be fetched, such as:
imgLogo.Src = "userImage.ashx?id=" + UserId + "&size=" + ImageSize;
where ImageSize is your defined variable.

checking uploaded image resolution and details at client side

In flex, what we do, we normally upload the image from flex end and upload it to the server,
i want to know, can we do some details checking, like i want to find out the image resolution(on the client side) before it is uploaded to the server,
There are going to be two profits, first the client doesn't need to wait for long to image get uploaded, and in case if finding the image resolution is on the server end, so it willtake time, even the image to be uploaded is not of expected resolution
second, the user interaction & interface with the flex application will be improved,
so, please give some idea to to this sort of checking from the flex end
If you mean the width/height measuring of a bitmap loaded into your flex app,
width/height is stored in BitmapData structure
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/BitmapData.html
For Image flex control it can be accessed with the construction:
// image_control is an instance of mx.controls.Image
var width:Number = 0;
var height:Number = 0;
if (image_control.content is Bitmap)
{
height= (image_control.content as Bitmap).bitmapData.width;
height= (image_control.content as Bitmap).bitmapData.height;
}
I suppose you're speaking of desktop app. Otherwise you woun't be able to touch any local file (you can only init it's uppload to server).
To work with jpg and png you can use com.adobe.images packages of as3corelib. Trere's able to get height/width or resolution of an image.
Although I belive it's better to perform manipulations with images on server-side
For flex, you can use the FileReference.browse function to load file from hard disk. If you want to check the width and height of the image, you can refer to Dmitry Sapelnikov's answer. If you want to check the total bytes of the image, you can try:
var bitmapByteSize:int = bitmap.bitmapData.getPixels(bitmap.bitmapData.rect).length;
Only checking the resolution of the image may not enough. If you need to modify the image, you may take a look on the following:
http://marstonstudio.com/2007/10/19/how-to-take-a-snapshot-of-a-flash-movie-and-automatically-upload-the-jpg-to-a-server-in-three-easy-steps/
It may give you some hints.
Is your Flex app a desktop app? If so you could load the file from the user's hard drive first, such as: http://mariusht.com/blog/2009/04/01/loading-local-images-directly-into-flash-player-10/
And then get the width and height (and probably a way to get the size) before sending it to a server.
BTW, the resolution of any image to be displayed on the web is always 72 DPI. You can't change the resolution of a jpeg or png for example, but you could print them at different resolutions. I think you are actually looking for the dimensions (width / height).

Resources