diff --git a/.changeset/four-pots-see.md b/.changeset/four-pots-see.md new file mode 100644 index 000000000000..9e5847f85af5 --- /dev/null +++ b/.changeset/four-pots-see.md @@ -0,0 +1,23 @@ +--- +'astro': minor +--- + +Adds a new, optional `kernel` configuration option to select a resize algorithm in the Sharp image service + +By default, Sharp resizes images with the `lanczos3` kernel. This new config option allows you to set the default resizing algorithm to any resizing option supported by [Sharp](https://sharp.pixelplumbing.com/api-resize/#resize) (e.g. `linear`, `mks2021`). + +Kernel selection can produce quite noticeable differences depending on various characteristics of the source image - especially drawn art - so changing the kernel gives you more control over the appearance of images on your site: + +```js +export default defineConfig({ + image: { + service: { + entrypoint: 'astro/assets/services/sharp', + config: { + kernel: "mks2021" + } + } +}) +``` + +This selection will apply to all images on your site, and is not yet configurable on a per-image basis. For more information, see [Sharps documentation on resizing images](https://sharp.pixelplumbing.com/api-resize/#resize). diff --git a/packages/astro/src/assets/services/sharp.ts b/packages/astro/src/assets/services/sharp.ts index 857d35442feb..b96193ec4891 100644 --- a/packages/astro/src/assets/services/sharp.ts +++ b/packages/astro/src/assets/services/sharp.ts @@ -1,4 +1,4 @@ -import type { FitEnum, FormatEnum, SharpOptions } from 'sharp'; +import type { FitEnum, FormatEnum, ResizeOptions, SharpOptions } from 'sharp'; import { AstroError, AstroErrorData } from '../../core/errors/index.js'; import type { ImageFit, ImageOutputFormat, ImageQualityPreset } from '../types.js'; import { @@ -13,6 +13,11 @@ export interface SharpImageServiceConfig { * The `limitInputPixels` option passed to Sharp. See https://sharp.pixelplumbing.com/api-constructor for more information */ limitInputPixels?: SharpOptions['limitInputPixels']; + + /** + * The `kernel` option is passed to resize calls. See https://sharp.pixelplumbing.com/api-resize/ for more information + */ + kernel?: ResizeOptions['kernel']; } let sharp: typeof import('sharp'); @@ -57,6 +62,7 @@ const sharpService: LocalImageService = { async transform(inputBuffer, transformOptions, config) { if (!sharp) sharp = await loadSharp(); const transform: BaseServiceTransform = transformOptions as BaseServiceTransform; + const kernel = config.service.config.kernel; // Return SVGs as-is // TODO: Sharp has some support for SVGs, we could probably support this once Sharp is the default and only service. @@ -81,6 +87,7 @@ const sharpService: LocalImageService = { result.resize({ width: Math.round(transform.width), height: Math.round(transform.height), + kernel: kernel, fit, position: transform.position, withoutEnlargement, @@ -88,11 +95,13 @@ const sharpService: LocalImageService = { } else if (transform.height && !transform.width) { result.resize({ height: Math.round(transform.height), + kernel: kernel, withoutEnlargement, }); } else if (transform.width) { result.resize({ width: Math.round(transform.width), + kernel: kernel, withoutEnlargement, }); } diff --git a/packages/astro/src/types/public/config.ts b/packages/astro/src/types/public/config.ts index 49368344fe06..daab1ce21e7f 100644 --- a/packages/astro/src/types/public/config.ts +++ b/packages/astro/src/types/public/config.ts @@ -1313,6 +1313,20 @@ export interface AstroUserConfig< * Set `false` to bypass the default image size limit for the Sharp image service and process large images. */ + /** + * @docs + * @name image.service.config.kernel + * @kind h4 + * @type {string | undefined} + * @default `undefined` + * @version 5.17.0 + * @description + * + * The default [kernel used for resizing images](https://sharp.pixelplumbing.com/api-resize/#resize) in the Sharp image service. + * + * By default this is `undefined`, which maps to Sharp's default kernel of `lanczos3`. + */ + /** * @docs * @name image.domains