Skip to content

Commit

Permalink
feat(thumbhash): rewrote thumbhash with native nodejs/ts implementation
Browse files Browse the repository at this point in the history
- added `/filters:thumbhash()/` to trigger this feature
  • Loading branch information
thisismana committed Jul 15, 2024
1 parent a008020 commit de55039
Show file tree
Hide file tree
Showing 7 changed files with 410 additions and 8 deletions.
3 changes: 1 addition & 2 deletions source/image-handler/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
},
"dependencies": {
"@aws-sdk/client-s3": "3.614.0",
"sharp": "0.33.4",
"thumbhash": "^0.1.1"
"sharp": "0.33.4"
},
"devDependencies": {
"@aws-lambda-powertools/logger": "2.4.0",
Expand Down
33 changes: 28 additions & 5 deletions source/image-handler/src/image-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
StatusCodes,
} from './lib';
import { S3 } from '@aws-sdk/client-s3';
import { rgbaToThumbHash, thumbHashToDataURL } from './lib/thumbhash';

export class ImageHandler {
private readonly LAMBDA_PAYLOAD_LIMIT = 6 * 1024 * 1024;
Expand Down Expand Up @@ -100,11 +101,15 @@ export class ImageHandler {

// apply image edits
let modifiedImage = await this.applyEdits(image, edits, options.animated);
// modify image output if requested
modifiedImage = this.modifyImageOutput(modifiedImage, imageRequestInfo);
// convert to base64 encoded string
const imageBuffer = await modifiedImage.toBuffer();
base64EncodedImage = imageBuffer.toString('base64');
if ('thumbhash' in edits) {
base64EncodedImage = await this.thumbhash(modifiedImage, imageRequestInfo);
} else {
// modify image output if requested
modifiedImage = this.modifyImageOutput(modifiedImage, imageRequestInfo);
// convert to base64 encoded string
const imageBuffer = await modifiedImage.toBuffer();
base64EncodedImage = imageBuffer.toString('base64');
}
} else {
// convert image to Sharp and change output format if specified
let image = await this.instantiateSharpImage(originalImage, edits, options);
Expand Down Expand Up @@ -153,6 +158,10 @@ export class ImageHandler {
case 'animated': {
break;
}
case 'thumbhash': {
originalImage.resize(100, 100, { fit: 'inside' });
break;
}
default: {
if (edit in originalImage) {
originalImage[edit](edits[edit]);
Expand Down Expand Up @@ -325,4 +334,18 @@ export class ImageHandler {
);
}
}

private async thumbhash(image: sharp.Sharp, imageRequestInfo: ImageRequestInfo): Promise<string> {
const { data, info } = await image.ensureAlpha().raw().toBuffer({ resolveWithObject: true });
const binaryThumbHash = rgbaToThumbHash(info.width, info.height, data);

imageRequestInfo.contentType = ContentTypes.JSON;
imageRequestInfo.cacheControl = 'max-age=3600';
return Buffer.from(
JSON.stringify({
base64: Buffer.from(binaryThumbHash).toString('base64'),
// base64_url: thumbHashToDataURL(binaryThumbHash), // debugging thedata:image/png;base64 if required, will be done in the frontend
}),
).toString('base64');
}
}
1 change: 1 addition & 0 deletions source/image-handler/src/lib/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,5 @@ export enum ContentTypes {
GIF = 'image/gif',
SVG = 'image/svg+xml',
AVIF = 'image/avif',
JSON = 'application/json',
}
Loading

0 comments on commit de55039

Please sign in to comment.