aboutsummaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2020-03-29 01:54:49 +0100
committerMitja Felicijan <mitja.felicijan@gmail.com>2020-03-29 01:54:49 +0100
commitc070cca569780abc2408b8e6c8841fb6cbf9effe (patch)
treebbe7a927a9645f0ab0aff011dd89fb86fdc2f3d2 /content
parent8e9b8977ae2dce61ac7b5899a52cc3e2bbe5dba9 (diff)
downloadmitjafelicijan.com-c070cca569780abc2408b8e6c8841fb6cbf9effe.tar.gz
Added new post
Diffstat (limited to 'content')
-rw-r--r--content/2020-03-25-create-placeholder-images-with-sharp.md9
-rw-r--r--content/2020-03-27-create-placeholder-images-with-sharp.md83
2 files changed, 83 insertions, 9 deletions
diff --git a/content/2020-03-25-create-placeholder-images-with-sharp.md b/content/2020-03-25-create-placeholder-images-with-sharp.md
deleted file mode 100644
index 6d35d82..0000000
--- a/content/2020-03-25-create-placeholder-images-with-sharp.md
+++ /dev/null
@@ -1,9 +0,0 @@
1~ title: Create placeholder images with sharp Node.js image processing library
2~ description: Create placeholder images with sharp Node.js image processing library
3~ slug: /create-placeholder-images-with-sharp.html
4~ date: 2020-03-25
5~ template: post
6~ hide: true
7
8## Todo
9
diff --git a/content/2020-03-27-create-placeholder-images-with-sharp.md b/content/2020-03-27-create-placeholder-images-with-sharp.md
new file mode 100644
index 0000000..1386b2f
--- /dev/null
+++ b/content/2020-03-27-create-placeholder-images-with-sharp.md
@@ -0,0 +1,83 @@
1~ title: Create placeholder images with sharp Node.js image processing library
2~ description: Create placeholder images with sharp Node.js image processing library
3~ slug: /create-placeholder-images-with-sharp.html
4~ date: 2020-03-27
5~ template: post
6~ hide: false
7
8I have been searching for a solution to pre-generate some placeholder images for image server I needed to develop that resizes images on S3. I though this would be a 15min job and quickly found out how very mistaken I was.
9
10Even though Node.js is not really the best way to do this kind of things (surely something written in C or Rust or even Golang would be the correct way to do this but we didn't need the speed in our case) I found an excellent library [sharp - High performance Node.js image processing](https://github.com/lovell/sharp).
11
12Getting things running was a breeze.
13
14## Fetch image from S3 and save resized
15
16```js
17const sharp = require('sharp');
18const aws = require('aws-sdk');
19
20const x,y = 100;
21const s3 = new aws.S3({});
22
23aws.config.update({
24 secretAccessKey: 'secretAccessKey',
25 accessKeyId: 'accessKeyId',
26 region: 'region'
27});
28
29const originalImage = await s3.getObject({
30 Bucket: 'some-bucket-name',
31 Key: 'image.jpg',
32}).promise();
33
34const resizedImage = await sharp(originalImage.Body)
35 .resize(100, 100)
36 .jpeg({ progressive: true })
37 .toBuffer();
38
39s3.putObject({
40 Bucket: 'some-bucket-name',
41 Key: `optimized/${x}x${y}/image.jpg`,
42 Body: resizedImage,
43 ContentType: 'image/jpeg',
44 ACL: 'public-read'
45}).promise();
46```
47
48All this code was wrapped inside a web service with some additional security checks and defensive coding to detect if key is missing on S3.
49
50And at that point I needed to return placeholder images as a response in case key is missing or x,y are not allowed by the server etc. I could have created PNG in Gimp and just serve them but I wanted to respect aspect ratio and I didn't want to return some mangled images.
51
52**ⓘ** Main problem with finding a clean solution I could copy and paste and change a bit was a task. API is changing constantly and there weren't clear examples or I was unable to find them.
53
54## Generating placeholder images using SVG
55
56What I ended up was using SVG to generate text and created image with sharp and used composition to combine both layers. Response returned by this function is a buffer you can use to either upload to S3 or save to local file.
57
58```js
59const generatePlaceholderImageWithText = async (width, height, message) => {
60 const overlay = `<svg width="${width - 20}" height="${height - 20}">
61 <text x="50%" y="50%" font-family="sans-serif" font-size="16" text-anchor="middle">${message}</text>
62 </svg>`;
63
64 return await sharp({
65 create: {
66 width: width,
67 height: height,
68 channels: 4,
69 background: { r: 230, g: 230, b: 230, alpha: 1 }
70 }
71 })
72 .composite([{
73 input: Buffer.from(overlay),
74 gravity: 'center',
75 }])
76 .jpeg()
77 .toBuffer();
78}
79```
80
81That is about it. Nothing more to it. You can change the color of the image by changing `background` and if you want to change text styling you can adapt SVG to your needs.
82
83**ⓘ** Also be careful about the length of the text. This function positions text at the center and adds `20px` padding on all sides. If text is longer than the image it will get cut.