﻿1
00:00:01,310 --> 00:00:04,140
‫In this video you're gonna learn about image processing

2
00:00:04,140 --> 00:00:06,930
‫and manipulation with Node JS,

3
00:00:06,930 --> 00:00:08,760
‫and in this particular case, we're going

4
00:00:08,760 --> 00:00:11,193
‫to resize and convert our images.

5
00:00:12,760 --> 00:00:15,140
‫So everywhere in our user interface

6
00:00:15,140 --> 00:00:18,490
‫we assume that the uploaded images are squares.

7
00:00:18,490 --> 00:00:20,250
‫So that we can then display them

8
00:00:20,250 --> 00:00:22,570
‫as circles like this.

9
00:00:22,570 --> 00:00:25,400
‫And so this only works when they are squares,

10
00:00:25,400 --> 00:00:27,260
‫but of course in the real world

11
00:00:27,260 --> 00:00:30,535
‫users are rarely going to be uploading images

12
00:00:30,535 --> 00:00:32,520
‫that are squares.

13
00:00:32,520 --> 00:00:34,600
‫And so our job now is to actually

14
00:00:34,600 --> 00:00:37,850
‫resize images to make them squares.

15
00:00:37,850 --> 00:00:41,300
‫Alright, and so here is how we're gonna do that.

16
00:00:41,300 --> 00:00:45,370
‫We will add yet another middleware before the update me

17
00:00:45,370 --> 00:00:47,570
‫and then that middleware will take care

18
00:00:47,570 --> 00:00:49,920
‫of the actual image processing.

19
00:00:49,920 --> 00:00:53,200
‫Alright, so actually let's do it here in the code

20
00:00:53,200 --> 00:00:54,470
‫right after this one,

21
00:00:54,470 --> 00:00:57,333
‫because they are kind of connected aren't they?

22
00:00:58,610 --> 00:01:00,623
‫So, exports dot,

23
00:01:01,690 --> 00:01:05,513
‫resize user photo.

24
00:01:13,250 --> 00:01:15,320
‫And before we continue, let's actually

25
00:01:15,320 --> 00:01:18,160
‫add this middleware to the middleware stack

26
00:01:18,160 --> 00:01:19,523
‫in this particular route.

27
00:01:20,870 --> 00:01:22,673
‫So that's in user routes,

28
00:01:23,860 --> 00:01:26,710
‫and so here right after the photo has been uploaded

29
00:01:26,710 --> 00:01:27,923
‫in this middleware,

30
00:01:29,410 --> 00:01:32,470
‫we will then resize it.

31
00:01:32,470 --> 00:01:35,180
‫So resize, and here it's actually

32
00:01:35,180 --> 00:01:36,603
‫the user controller.

33
00:01:41,130 --> 00:01:42,710
‫Alright.

34
00:01:42,710 --> 00:01:44,060
‫Let's actually go down here

35
00:01:45,620 --> 00:01:47,320
‫and going back.

36
00:01:47,320 --> 00:01:49,480
‫And so at this point we already have

37
00:01:49,480 --> 00:01:51,540
‫the file on our request.

38
00:01:51,540 --> 00:01:53,500
‫At least if there was an upload,

39
00:01:53,500 --> 00:01:55,000
‫and if there was no upload,

40
00:01:55,000 --> 00:01:57,280
‫then of course we don't want to do anything.

41
00:01:57,280 --> 00:02:00,163
‫So that means that we want to go to the next middleware.

42
00:02:01,090 --> 00:02:03,680
‫So if there is no file on the request

43
00:02:05,230 --> 00:02:10,230
‫then return right away and go to next.

44
00:02:10,960 --> 00:02:13,380
‫Okay, but otherwise we of course, then

45
00:02:13,380 --> 00:02:15,700
‫want to do that image resizing.

46
00:02:15,700 --> 00:02:19,690
‫And for that, we are going to use the sharp package.

47
00:02:19,690 --> 00:02:20,890
‫Alright.

48
00:02:20,890 --> 00:02:24,453
‫So, well first of all let's actually install it.

49
00:02:25,630 --> 00:02:28,710
‫So MPM install sharp

50
00:02:32,190 --> 00:02:35,720
‫Alright, and since that is doing its work

51
00:02:35,720 --> 00:02:38,533
‫let's go ahead and put that here already.

52
00:02:39,500 --> 00:02:40,463
‫So sharp,

53
00:02:41,940 --> 00:02:45,600
‫and require, sharp.

54
00:02:45,600 --> 00:02:47,360
‫And sharp is a really nice and

55
00:02:47,360 --> 00:02:51,230
‫easy to use image processing library for Node Js

56
00:02:51,230 --> 00:02:52,590
‫And there's fairly a lot of stuff

57
00:02:52,590 --> 00:02:53,930
‫that we can do with it.

58
00:02:53,930 --> 00:02:55,970
‫But where it really shines is for

59
00:02:55,970 --> 00:02:59,150
‫resizing images in a very simple way.

60
00:02:59,150 --> 00:03:03,690
‫And so, that's exactly what we're looking for here.

61
00:03:03,690 --> 00:03:04,550
‫Alright.

62
00:03:04,550 --> 00:03:08,590
‫So, we say sharp and then here

63
00:03:08,590 --> 00:03:11,180
‫we basically need to pass in the file.

64
00:03:11,180 --> 00:03:13,990
‫Now, when doing image processing like this

65
00:03:13,990 --> 00:03:16,120
‫right after uploading a file,

66
00:03:16,120 --> 00:03:19,310
‫then it's always best to not even save the file

67
00:03:19,310 --> 00:03:22,770
‫to the disk, but instead save it to memory.

68
00:03:22,770 --> 00:03:24,580
‫We already talked about that before,

69
00:03:24,580 --> 00:03:27,130
‫and so that's now actually do that in practice.

70
00:03:27,130 --> 00:03:29,930
‫Okay, so for that we need to change

71
00:03:29,930 --> 00:03:32,830
‫a little bit or multer configuration

72
00:03:32,830 --> 00:03:35,230
‫and actually just this multer storage,

73
00:03:35,230 --> 00:03:38,703
‫because now we no longer need any of this.

74
00:03:40,600 --> 00:03:42,453
‫And instead to multer storage,

75
00:03:45,700 --> 00:03:50,700
‫will be simply multer dot memory storage.

76
00:03:52,250 --> 00:03:54,810
‫And just like this, okay?

77
00:03:54,810 --> 00:03:56,720
‫And so as I mentioned earlier,

78
00:03:56,720 --> 00:04:00,730
‫this way the image will then be stored as a buffer.

79
00:04:00,730 --> 00:04:03,080
‫And so that buffer is then available

80
00:04:03,080 --> 00:04:07,820
‫at request dot file dot buffer

81
00:04:07,820 --> 00:04:10,500
‫and so this is way more efficient like this,

82
00:04:10,500 --> 00:04:13,600
‫so instead of having to write the file to the disk

83
00:04:13,600 --> 00:04:15,330
‫and then here read it again.

84
00:04:15,330 --> 00:04:17,860
‫We simply keep the image basically in memory

85
00:04:17,860 --> 00:04:20,960
‫and then here we can read that, alright?

86
00:04:20,960 --> 00:04:23,181
‫Anyway, calling the sharp function like this here

87
00:04:23,181 --> 00:04:26,300
‫will then create an object on which we can chain

88
00:04:26,300 --> 00:04:29,750
‫multiple methods in order to do our image processing.

89
00:04:29,750 --> 00:04:32,913
‫And so the first one that we're going to do is resize.

90
00:04:34,040 --> 00:04:36,740
‫So, resize, and then here we can specify

91
00:04:36,740 --> 00:04:38,480
‫the width and the height.

92
00:04:38,480 --> 00:04:42,480
‫And so let's say 500 and 500

93
00:04:42,480 --> 00:04:44,780
‫so remember we want square images,

94
00:04:44,780 --> 00:04:47,220
‫and so of course, the height needs to be

95
00:04:47,220 --> 00:04:48,770
‫the same as the width.

96
00:04:48,770 --> 00:04:50,750
‫Now this will then crop the image

97
00:04:50,750 --> 00:04:55,050
‫so that it covers this entire 500 times 500 square.

98
00:04:55,050 --> 00:04:56,400
‫And actually we can change

99
00:04:56,400 --> 00:04:59,130
‫this default behavior if we wanted to.

100
00:04:59,130 --> 00:05:01,320
‫And so, let's again, take a quick look

101
00:05:01,320 --> 00:05:02,563
‫at the documentation.

102
00:05:04,860 --> 00:05:09,053
‫So let's say, github sharp,

103
00:05:09,990 --> 00:05:12,100
‫but actually their own website

104
00:05:12,100 --> 00:05:14,440
‫is a bit better, a bit more complete.

105
00:05:14,440 --> 00:05:18,360
‫So let's click that link here, and so then

106
00:05:18,360 --> 00:05:20,770
‫here we can come to resizing,

107
00:05:20,770 --> 00:05:22,780
‫which is what we're currently doing

108
00:05:22,780 --> 00:05:25,153
‫and then here is what I was just talking about.

109
00:05:26,110 --> 00:05:29,130
‫Alright, so the default here is that image

110
00:05:29,130 --> 00:05:31,070
‫will be cropped in order to cover

111
00:05:31,070 --> 00:05:33,610
‫both the provided dimensions.

112
00:05:33,610 --> 00:05:38,610
‫But we can also choose contain, fill, inside, or outside.

113
00:05:39,280 --> 00:05:43,310
‫And, we would do that by setting the options here.

114
00:05:43,310 --> 00:05:46,700
‫So we can set width, height, and then as a third option,

115
00:05:46,700 --> 00:05:48,830
‫we could set this options object

116
00:05:48,830 --> 00:05:52,070
‫where we can then define the fit.

117
00:05:52,070 --> 00:05:54,560
‫We could also define the position,

118
00:05:54,560 --> 00:05:56,433
‫which is center by default.

119
00:05:58,970 --> 00:06:00,653
‫You see that there's all kinds of stuff

120
00:06:00,653 --> 00:06:03,420
‫that we could really define to fine tune

121
00:06:03,420 --> 00:06:04,670
‫our image processing.

122
00:06:04,670 --> 00:06:07,653
‫But in this case, what we have is enough.

123
00:06:08,550 --> 00:06:10,720
‫So let's move on to the next step.

124
00:06:10,720 --> 00:06:12,990
‫Because what I want to do next is actually

125
00:06:12,990 --> 00:06:16,450
‫convert the images always to jpeg, okay?

126
00:06:16,450 --> 00:06:18,863
‫And for that, we use to format,

127
00:06:21,640 --> 00:06:23,463
‫and then jpeg.

128
00:06:25,000 --> 00:06:28,180
‫We can also then define the quality of this jpeg.

129
00:06:28,180 --> 00:06:30,170
‫So basically to compress it a little bit

130
00:06:30,170 --> 00:06:32,310
‫so that it doesn't take up so much space

131
00:06:33,230 --> 00:06:36,900
‫and so for that, we use the jpeg method,

132
00:06:36,900 --> 00:06:41,900
‫and set an option in this object with quality

133
00:06:42,290 --> 00:06:45,043
‫and let's say 90 percent here, alright?

134
00:06:46,910 --> 00:06:49,860
‫So each method into its own line here

135
00:06:49,860 --> 00:06:53,210
‫that's much nicer, but actually we're not done.

136
00:06:53,210 --> 00:06:56,020
‫We're almost done, but not entirely.

137
00:06:56,020 --> 00:06:57,460
‫Because now, in the end,

138
00:06:57,460 --> 00:07:01,850
‫we then, finally want to write it to a file on our disk.

139
00:07:01,850 --> 00:07:04,913
‫And so for that, we can use to file,

140
00:07:06,230 --> 00:07:08,550
‫now this method here actually needs

141
00:07:08,550 --> 00:07:10,940
‫the entire path to the file.

142
00:07:10,940 --> 00:07:13,180
‫So basically public

143
00:07:14,240 --> 00:07:17,440
‫images, slash, users,

144
00:07:17,440 --> 00:07:20,460
‫and then finally here the file name, alright?

145
00:07:20,460 --> 00:07:21,990
‫So let's get that actually from what

146
00:07:21,990 --> 00:07:23,550
‫we had here before.

147
00:07:23,550 --> 00:07:25,840
‫Because of course, we want our images

148
00:07:25,840 --> 00:07:27,183
‫to have a similar format.

149
00:07:29,520 --> 00:07:32,380
‫Alright, so let's copy that.

150
00:07:32,380 --> 00:07:34,723
‫But actually I will not put it right here.

151
00:07:35,790 --> 00:07:38,010
‫Instead, I will actually save it to

152
00:07:38,010 --> 00:07:42,443
‫request dot file dot file name.

153
00:07:43,490 --> 00:07:45,777
‫Now why am I doing it like this?

154
00:07:45,777 --> 00:07:48,280
‫Well it's because right now this file

155
00:07:48,280 --> 00:07:50,340
‫name is not defined.

156
00:07:50,340 --> 00:07:55,340
‫So, when we decide to save the image into memory

157
00:07:56,270 --> 00:08:00,050
‫so as a buffer, the file name will not really get set,

158
00:08:00,050 --> 00:08:02,300
‫but we really need that file name

159
00:08:02,300 --> 00:08:05,050
‫in our other middleware function, right?

160
00:08:05,050 --> 00:08:09,310
‫So that's down here in update me right here.

161
00:08:09,310 --> 00:08:12,360
‫So we rely on request dot file dot file name

162
00:08:12,360 --> 00:08:16,400
‫in order to save the file name into our database, right?

163
00:08:16,400 --> 00:08:19,770
‫And so actually, we should define that.

164
00:08:19,770 --> 00:08:22,442
‫And so, previously it was of course defined

165
00:08:22,442 --> 00:08:25,970
‫by the multer upload that we had, but since

166
00:08:25,970 --> 00:08:30,323
‫that is gone now, we should then basically redefine it here.

167
00:08:31,320 --> 00:08:32,260
‫Okay?

168
00:08:32,260 --> 00:08:34,560
‫Then here, actually, we can get rid of this part

169
00:08:34,560 --> 00:08:37,020
‫of the extension, because we already know

170
00:08:37,020 --> 00:08:39,460
‫that it will always be a jpeg.

171
00:08:39,460 --> 00:08:42,570
‫Because of this to format, okay?

172
00:08:42,570 --> 00:08:45,513
‫And so here, we can simply put jpeg.

173
00:08:47,130 --> 00:08:50,383
‫So there's no need to get the file extension.

174
00:08:51,320 --> 00:08:52,263
‫And so now here,

175
00:08:54,610 --> 00:08:55,993
‫we can then use that.

176
00:08:56,911 --> 00:09:00,890
‫Req dot file dot file name,

177
00:09:00,890 --> 00:09:02,403
‫and that's actually it.

178
00:09:04,020 --> 00:09:04,853
‫Okay?

179
00:09:04,853 --> 00:09:06,820
‫So all we need to do now to finish

180
00:09:06,820 --> 00:09:10,790
‫is to then actually call the next middleware in the stack.

181
00:09:10,790 --> 00:09:14,430
‫And so that will be the update me handler function.

182
00:09:14,430 --> 00:09:17,603
‫So of course, let's now actually test that.

183
00:09:18,530 --> 00:09:21,280
‫So, we no longer need this one.

184
00:09:21,280 --> 00:09:23,390
‫Let's come here to Postman,

185
00:09:23,390 --> 00:09:25,240
‫and now the user that I want to update

186
00:09:25,240 --> 00:09:28,410
‫is called arrav, I think.

187
00:09:28,410 --> 00:09:31,053
‫Let's take a look here at our data very quick.

188
00:09:32,520 --> 00:09:35,910
‫And so yeah, so this is the non square image

189
00:09:35,910 --> 00:09:38,070
‫that we're going to be uploading now

190
00:09:38,070 --> 00:09:39,800
‫and actually you see the size here

191
00:09:39,800 --> 00:09:42,600
‫which is 1000 times 1500,

192
00:09:42,600 --> 00:09:44,540
‫and so let's later compare that with

193
00:09:44,540 --> 00:09:46,223
‫our resized uploaded image.

194
00:09:47,110 --> 00:09:48,090
‫Alright.

195
00:09:48,090 --> 00:09:51,090
‫Anyway, let's now get the name for arrav

196
00:09:52,120 --> 00:09:55,720
‫Actually we don't need, they're always the same so

197
00:09:56,840 --> 00:10:01,010
‫arrav like this, so let's log in.

198
00:10:01,010 --> 00:10:02,930
‫So that we can then update it

199
00:10:02,930 --> 00:10:07,530
‫and you see that right now is image here is user 11.

200
00:10:07,530 --> 00:10:09,620
‫And just to see it a bit better

201
00:10:09,620 --> 00:10:11,400
‫let's actually update,

202
00:10:11,400 --> 00:10:15,370
‫let's actually log in, into our web application

203
00:10:15,370 --> 00:10:16,543
‫using that user.

204
00:10:21,820 --> 00:10:23,883
‫So test one, two, three, four.

205
00:10:26,420 --> 00:10:29,490
‫Alright, so that is the current image

206
00:10:29,490 --> 00:10:32,233
‫and now let's go ahead and update that.

207
00:10:37,120 --> 00:10:40,260
‫Select files, and here is our image

208
00:10:41,330 --> 00:10:44,900
‫open that and let's see what happens.

209
00:10:44,900 --> 00:10:46,290
‫And we're done.

210
00:10:46,290 --> 00:10:47,980
‫That was actually very quick,

211
00:10:47,980 --> 00:10:50,430
‫so let's see if it's correct.

212
00:10:50,430 --> 00:10:53,023
‫Well at least the name here seems correct.

213
00:10:54,590 --> 00:10:59,590
‫If we take a look at our users now here,

214
00:10:59,750 --> 00:11:02,900
‫that's in public, or right here.

215
00:11:02,900 --> 00:11:04,520
‫So that should be the one

216
00:11:04,520 --> 00:11:05,420
‫actually it's not.

217
00:11:07,610 --> 00:11:10,070
‫And actually it's nowhere to be found.

218
00:11:10,070 --> 00:11:11,710
‫Let's reload,

219
00:11:11,710 --> 00:11:12,913
‫ah, and here it is.

220
00:11:14,380 --> 00:11:15,493
‫Now, that's the one.

221
00:11:16,580 --> 00:11:20,060
‫So you see that now it's at 500 times 500

222
00:11:20,060 --> 00:11:21,700
‫it's much smaller here,

223
00:11:21,700 --> 00:11:26,560
‫so 55 compared to the 315 we had before.

224
00:11:26,560 --> 00:11:28,180
‫So that's a lot better,

225
00:11:28,180 --> 00:11:31,740
‫and as you will see here, it should

226
00:11:31,740 --> 00:11:34,310
‫now be updated here as well.

227
00:11:34,310 --> 00:11:36,050
‫And that's perfect.

228
00:11:36,050 --> 00:11:39,650
‫So the face is actually right in the middle here.

229
00:11:39,650 --> 00:11:43,730
‫So that resizing really went kinda perfect.

230
00:11:43,730 --> 00:11:44,563
‫Cool.

231
00:11:44,563 --> 00:11:46,530
‫And I hope you will find some use

232
00:11:46,530 --> 00:11:48,810
‫for this kind of image processing in

233
00:11:48,810 --> 00:11:51,290
‫your own applications as well.

234
00:11:51,290 --> 00:11:54,660
‫So just to quickly recap what did we do here.

235
00:11:54,660 --> 00:11:57,340
‫Well we created a new middleware function

236
00:11:57,340 --> 00:11:59,490
‫that is going to be running right after

237
00:11:59,490 --> 00:12:01,460
‫the photo is actually uploaded.

238
00:12:01,460 --> 00:12:03,850
‫And that upload is now actually happening

239
00:12:03,850 --> 00:12:07,860
‫to a buffer and no longer directly to the file system.

240
00:12:07,860 --> 00:12:08,693
‫Right?

241
00:12:08,693 --> 00:12:11,163
‫And so that's why we use this memory storage here,

242
00:12:12,010 --> 00:12:14,950
‫but of course this multer filter here

243
00:12:14,950 --> 00:12:16,420
‫is still working.

244
00:12:16,420 --> 00:12:20,063
‫And so we can still only upload images, alright?

245
00:12:20,980 --> 00:12:23,510
‫So then here in that middleware

246
00:12:23,510 --> 00:12:25,600
‫we put that image's file name on

247
00:12:25,600 --> 00:12:28,000
‫request dot file dot file name

248
00:12:28,000 --> 00:12:30,200
‫so that we can then use it in the update me.

249
00:12:31,100 --> 00:12:33,510
‫Alright, and then here we have the

250
00:12:33,510 --> 00:12:35,670
‫actual image processing itself.

251
00:12:35,670 --> 00:12:38,330
‫Where we first resized it to a square

252
00:12:38,330 --> 00:12:40,120
‫and then formatted to a jpeg

253
00:12:40,120 --> 00:12:43,010
‫with a quality of 90 percent, and finally

254
00:12:43,010 --> 00:12:45,930
‫we then write that file into our file system

255
00:12:45,930 --> 00:12:50,710
‫to the exact same folder that we specified also before.

256
00:12:50,710 --> 00:12:53,260
‫Alright, so this is how it works

257
00:12:53,260 --> 00:12:55,040
‫when you need some image processing,

258
00:12:55,040 --> 00:12:57,310
‫but if you do not need it, then of course

259
00:12:57,310 --> 00:13:00,500
‫you can keep using it this way, okay?

260
00:13:00,500 --> 00:13:02,210
‫And so that's really important

261
00:13:02,210 --> 00:13:03,450
‫that we learned how to do it

262
00:13:03,450 --> 00:13:05,160
‫in both ways here.

263
00:13:05,160 --> 00:13:07,380
‫Alright, next up in the next video

264
00:13:07,380 --> 00:13:10,462
‫we will then actually make this form here work

265
00:13:10,462 --> 00:13:12,700
‫so that we can upload to user photos

266
00:13:12,700 --> 00:13:14,633
‫directly from here.

