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