From 7abfce4634e66cf60c87946265fa023dff7d1d10 Mon Sep 17 00:00:00 2001 From: egor-romanov <egor.romanov@gmail.com> Date: Mon, 4 Dec 2023 22:17:18 +0400 Subject: [PATCH 1/4] feat: add gravity param for image transformation --- src/http/schemas/transformations.ts | 3 +++ src/storage/renderer/image.ts | 33 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/http/schemas/transformations.ts b/src/http/schemas/transformations.ts index 907dd154..2932d59c 100644 --- a/src/http/schemas/transformations.ts +++ b/src/http/schemas/transformations.ts @@ -4,4 +4,7 @@ export const transformationOptionsSchema = { resize: { type: 'string', enum: ['cover', 'contain', 'fill'] }, format: { type: 'string', enum: ['origin', 'avif'] }, quality: { type: 'integer', minimum: 20, maximum: 100 }, + gravity: { type: 'string', enum: ['no', 'so', 'ea', 'we', 'noea', 'nowe', 'soea', 'sowe', 'ce', 'sm', 'fp'] }, + x_offset: { type: 'number', examples: [0.1, 100], minimum: 0 }, + y_offset: { type: 'number', examples: [0.1, 100], minimum: 0 }, } as const diff --git a/src/storage/renderer/image.ts b/src/storage/renderer/image.ts index d09bdcdf..e41b9011 100644 --- a/src/storage/renderer/image.ts +++ b/src/storage/renderer/image.ts @@ -17,6 +17,9 @@ export interface TransformOptions { resize?: 'cover' | 'contain' | 'fill' format?: 'origin' | 'avif' quality?: number + gravity?: 'no' | 'so' | 'ea' | 'we' | 'noea' | 'nowe' | 'soea' | 'sowe' | 'ce' | 'sm' | 'fp' + x_offset?: number + y_offset?: number } const { @@ -115,6 +118,27 @@ export class ImageRenderer extends Renderer { segments.push(`format:${options.format}`) } + if (options.gravity) { + switch (options.gravity) { + case 'sm': { + segments.push(`gravity:${options.gravity}`) + break + } + case 'fp': { + if (!(options.x_offset && options.y_offset && + options.x_offset <= 1 && options.y_offset <= 1 && + options.x_offset >= -1 && options.y_offset >= -1)) { + throw new StorageBackendError('Invalid focus point', 400, 'Focal point requires x and y coordinates within 0-1 range') + } + segments.push(`gravity:${options.gravity}:${options.x_offset}:${options.y_offset}`) + break + } + default: { + segments.push(`gravity:${options.gravity}:${options.x_offset ?? 0}:${options.y_offset ?? 0}`) + } + } + } + return segments } @@ -170,6 +194,15 @@ export class ImageRenderer extends Renderer { case 'quality': all.quality = parseInt(value, 10) break + case 'gravity': + all.gravity = value + break + case 'x_offset': + all.x_offset = parseFloat(value) + break + case 'y_offset': + all.y_offset = parseFloat(value) + break } return all }, {} as TransformOptions) From 29b541ecbc13ed0ac5e929576b3c7b9ec52e97e6 Mon Sep 17 00:00:00 2001 From: egor-romanov <egor.romanov@gmail.com> Date: Mon, 4 Dec 2023 22:26:18 +0400 Subject: [PATCH 2/4] fix: offset can be negative --- src/http/schemas/transformations.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/http/schemas/transformations.ts b/src/http/schemas/transformations.ts index 2932d59c..c6ca3568 100644 --- a/src/http/schemas/transformations.ts +++ b/src/http/schemas/transformations.ts @@ -5,6 +5,6 @@ export const transformationOptionsSchema = { format: { type: 'string', enum: ['origin', 'avif'] }, quality: { type: 'integer', minimum: 20, maximum: 100 }, gravity: { type: 'string', enum: ['no', 'so', 'ea', 'we', 'noea', 'nowe', 'soea', 'sowe', 'ce', 'sm', 'fp'] }, - x_offset: { type: 'number', examples: [0.1, 100], minimum: 0 }, - y_offset: { type: 'number', examples: [0.1, 100], minimum: 0 }, + x_offset: { type: 'number', examples: [0.1, 100] }, + y_offset: { type: 'number', examples: [0.1, -100] }, } as const From 65fa2dd6901c3a11177478e7e9a7bc49ed4474b2 Mon Sep 17 00:00:00 2001 From: egor-romanov <egor.romanov@gmail.com> Date: Mon, 4 Dec 2023 22:38:18 +0400 Subject: [PATCH 3/4] fix: prettier --- src/http/schemas/transformations.ts | 5 ++++- src/storage/renderer/image.ts | 23 ++++++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/http/schemas/transformations.ts b/src/http/schemas/transformations.ts index c6ca3568..2333c650 100644 --- a/src/http/schemas/transformations.ts +++ b/src/http/schemas/transformations.ts @@ -4,7 +4,10 @@ export const transformationOptionsSchema = { resize: { type: 'string', enum: ['cover', 'contain', 'fill'] }, format: { type: 'string', enum: ['origin', 'avif'] }, quality: { type: 'integer', minimum: 20, maximum: 100 }, - gravity: { type: 'string', enum: ['no', 'so', 'ea', 'we', 'noea', 'nowe', 'soea', 'sowe', 'ce', 'sm', 'fp'] }, + gravity: { + type: 'string', + enum: ['no', 'so', 'ea', 'we', 'noea', 'nowe', 'soea', 'sowe', 'ce', 'sm', 'fp'], + }, x_offset: { type: 'number', examples: [0.1, 100] }, y_offset: { type: 'number', examples: [0.1, -100] }, } as const diff --git a/src/storage/renderer/image.ts b/src/storage/renderer/image.ts index e41b9011..26824a4d 100644 --- a/src/storage/renderer/image.ts +++ b/src/storage/renderer/image.ts @@ -125,16 +125,29 @@ export class ImageRenderer extends Renderer { break } case 'fp': { - if (!(options.x_offset && options.y_offset && - options.x_offset <= 1 && options.y_offset <= 1 && - options.x_offset >= -1 && options.y_offset >= -1)) { - throw new StorageBackendError('Invalid focus point', 400, 'Focal point requires x and y coordinates within 0-1 range') + if ( + !( + options.x_offset && + options.y_offset && + options.x_offset <= 1 && + options.y_offset <= 1 && + options.x_offset >= -1 && + options.y_offset >= -1 + ) + ) { + throw new StorageBackendError( + 'Invalid focus point', + 400, + 'Focal point requires x and y coordinates within 0-1 range' + ) } segments.push(`gravity:${options.gravity}:${options.x_offset}:${options.y_offset}`) break } default: { - segments.push(`gravity:${options.gravity}:${options.x_offset ?? 0}:${options.y_offset ?? 0}`) + segments.push( + `gravity:${options.gravity}:${options.x_offset ?? 0}:${options.y_offset ?? 0}` + ) } } } From 63ed13f8e47c33418878940398a6116e5201b0da Mon Sep 17 00:00:00 2001 From: egor-romanov <egor.romanov@gmail.com> Date: Tue, 5 Dec 2023 19:40:14 +0400 Subject: [PATCH 4/4] fix: fp x and y boundaries --- src/storage/renderer/image.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storage/renderer/image.ts b/src/storage/renderer/image.ts index 26824a4d..985dd101 100644 --- a/src/storage/renderer/image.ts +++ b/src/storage/renderer/image.ts @@ -131,8 +131,8 @@ export class ImageRenderer extends Renderer { options.y_offset && options.x_offset <= 1 && options.y_offset <= 1 && - options.x_offset >= -1 && - options.y_offset >= -1 + options.x_offset >= 0 && + options.y_offset >= 0 ) ) { throw new StorageBackendError(