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