‫In this video you're gonna learn about image processing
‫and manipulation with Node JS,
‫and in this particular case, we're going
‫to resize and convert our images.
‫So everywhere in our user interface
‫we assume that the uploaded images are squares.
‫So that we can then display them
‫as circles like this.
‫And so this only works when they are squares,
‫but of course in the real world
‫users are rarely going to be uploading images
‫that are squares.
‫And so our job now is to actually
‫resize images to make them squares.
‫Alright, and so here is how we're gonna do that.
‫We will add yet another middleware before the update me
‫and then that middleware will take care
‫of the actual image processing.
‫Alright, so actually let's do it here in the code
‫right after this one,
‫because they are kind of connected aren't they?
‫So, exports dot,
‫resize user photo.
‫And before we continue, let's actually
‫add this middleware to the middleware stack
‫in this particular route.
‫So that's in user routes,
‫and so here right after the photo has been uploaded
‫in this middleware,
‫we will then resize it.
‫So resize, and here it's actually
‫the user controller.
‫Alright.
‫Let's actually go down here
‫and going back.
‫And so at this point we already have
‫the file on our request.
‫At least if there was an upload,
‫and if there was no upload,
‫then of course we don't want to do anything.
‫So that means that we want to go to the next middleware.
‫So if there is no file on the request
‫then return right away and go to next.
‫Okay, but otherwise we of course, then
‫want to do that image resizing.
‫And for that, we are going to use the sharp package.
‫Alright.
‫So, well first of all let's actually install it.
‫So MPM install sharp
‫Alright, and since that is doing its work
‫let's go ahead and put that here already.
‫So sharp,
‫and require, sharp.
‫And sharp is a really nice and
‫easy to use image processing library for Node Js
‫And there's fairly a lot of stuff
‫that we can do with it.
‫But where it really shines is for
‫resizing images in a very simple way.
‫And so, that's exactly what we're looking for here.
‫Alright.
‫So, we say sharp and then here
‫we basically need to pass in the file.
‫Now, when doing image processing like this
‫right after uploading a file,
‫then it's always best to not even save the file
‫to the disk, but instead save it to memory.
‫We already talked about that before,
‫and so that's now actually do that in practice.
‫Okay, so for that we need to change
‫a little bit or multer configuration
‫and actually just this multer storage,
‫because now we no longer need any of this.
‫And instead to multer storage,
‫will be simply multer dot memory storage.
‫And just like this, okay?
‫And so as I mentioned earlier,
‫this way the image will then be stored as a buffer.
‫And so that buffer is then available
‫at request dot file dot buffer
‫and so this is way more efficient like this,
‫so instead of having to write the file to the disk
‫and then here read it again.
‫We simply keep the image basically in memory
‫and then here we can read that, alright?
‫Anyway, calling the sharp function like this here
‫will then create an object on which we can chain
‫multiple methods in order to do our image processing.
‫And so the first one that we're going to do is resize.
‫So, resize, and then here we can specify
‫the width and the height.
‫And so let's say 500 and 500
‫so remember we want square images,
‫and so of course, the height needs to be
‫the same as the width.
‫Now this will then crop the image
‫so that it covers this entire 500 times 500 square.
‫And actually we can change
‫this default behavior if we wanted to.
‫And so, let's again, take a quick look
‫at the documentation.
‫So let's say, github sharp,
‫but actually their own website
‫is a bit better, a bit more complete.
‫So let's click that link here, and so then
‫here we can come to resizing,
‫which is what we're currently doing
‫and then here is what I was just talking about.
‫Alright, so the default here is that image
‫will be cropped in order to cover
‫both the provided dimensions.
‫But we can also choose contain, fill, inside, or outside.
‫And, we would do that by setting the options here.
‫So we can set width, height, and then as a third option,
‫we could set this options object
‫where we can then define the fit.
‫We could also define the position,
‫which is center by default.
‫You see that there's all kinds of stuff
‫that we could really define to fine tune
‫our image processing.
‫But in this case, what we have is enough.
‫So let's move on to the next step.
‫Because what I want to do next is actually
‫convert the images always to jpeg, okay?
‫And for that, we use to format,
‫and then jpeg.
‫We can also then define the quality of this jpeg.
‫So basically to compress it a little bit
‫so that it doesn't take up so much space
‫and so for that, we use the jpeg method,
‫and set an option in this object with quality
‫and let's say 90 percent here, alright?
‫So each method into its own line here
‫that's much nicer, but actually we're not done.
‫We're almost done, but not entirely.
‫Because now, in the end,
‫we then, finally want to write it to a file on our disk.
‫And so for that, we can use to file,
‫now this method here actually needs
‫the entire path to the file.
‫So basically public
‫images, slash, users,
‫and then finally here the file name, alright?
‫So let's get that actually from what
‫we had here before.
‫Because of course, we want our images
‫to have a similar format.
‫Alright, so let's copy that.
‫But actually I will not put it right here.
‫Instead, I will actually save it to
‫request dot file dot file name.
‫Now why am I doing it like this?
‫Well it's because right now this file
‫name is not defined.
‫So, when we decide to save the image into memory
‫so as a buffer, the file name will not really get set,
‫but we really need that file name
‫in our other middleware function, right?
‫So that's down here in update me right here.
‫So we rely on request dot file dot file name
‫in order to save the file name into our database, right?
‫And so actually, we should define that.
‫And so, previously it was of course defined
‫by the multer upload that we had, but since
‫that is gone now, we should then basically redefine it here.
‫Okay?
‫Then here, actually, we can get rid of this part
‫of the extension, because we already know
‫that it will always be a jpeg.
‫Because of this to format, okay?
‫And so here, we can simply put jpeg.
‫So there's no need to get the file extension.
‫And so now here,
‫we can then use that.
‫Req dot file dot file name,
‫and that's actually it.
‫Okay?
‫So all we need to do now to finish
‫is to then actually call the next middleware in the stack.
‫And so that will be the update me handler function.
‫So of course, let's now actually test that.
‫So, we no longer need this one.
‫Let's come here to Postman,
‫and now the user that I want to update
‫is called arrav, I think.
‫Let's take a look here at our data very quick.
‫And so yeah, so this is the non square image
‫that we're going to be uploading now
‫and actually you see the size here
‫which is 1000 times 1500,
‫and so let's later compare that with
‫our resized uploaded image.
‫Alright.
‫Anyway, let's now get the name for arrav
‫Actually we don't need, they're always the same so
‫arrav like this, so let's log in.
‫So that we can then update it
‫and you see that right now is image here is user 11.
‫And just to see it a bit better
‫let's actually update,
‫let's actually log in, into our web application
‫using that user.
‫So test one, two, three, four.
‫Alright, so that is the current image
‫and now let's go ahead and update that.
‫Select files, and here is our image
‫open that and let's see what happens.
‫And we're done.
‫That was actually very quick,
‫so let's see if it's correct.
‫Well at least the name here seems correct.
‫If we take a look at our users now here,
‫that's in public, or right here.
‫So that should be the one
‫actually it's not.
‫And actually it's nowhere to be found.
‫Let's reload,
‫ah, and here it is.
‫Now, that's the one.
‫So you see that now it's at 500 times 500
‫it's much smaller here,
‫so 55 compared to the 315 we had before.
‫So that's a lot better,
‫and as you will see here, it should
‫now be updated here as well.
‫And that's perfect.
‫So the face is actually right in the middle here.
‫So that resizing really went kinda perfect.
‫Cool.
‫And I hope you will find some use
‫for this kind of image processing in
‫your own applications as well.
‫So just to quickly recap what did we do here.
‫Well we created a new middleware function
‫that is going to be running right after
‫the photo is actually uploaded.
‫And that upload is now actually happening
‫to a buffer and no longer directly to the file system.
‫Right?
‫And so that's why we use this memory storage here,
‫but of course this multer filter here
‫is still working.
‫And so we can still only upload images, alright?
‫So then here in that middleware
‫we put that image's file name on
‫request dot file dot file name
‫so that we can then use it in the update me.
‫Alright, and then here we have the
‫actual image processing itself.
‫Where we first resized it to a square
‫and then formatted to a jpeg
‫with a quality of 90 percent, and finally
‫we then write that file into our file system
‫to the exact same folder that we specified also before.
‫Alright, so this is how it works
‫when you need some image processing,
‫but if you do not need it, then of course
‫you can keep using it this way, okay?
‫And so that's really important
‫that we learned how to do it
‫in both ways here.
‫Alright, next up in the next video
‫we will then actually make this form here work
‫so that we can upload to user photos
‫directly from here.