Skip to content

图片服务 API

astro:assets 旨在让任何图片优化服务都能轻松地在 Astro 之上构建服务。

¥astro:assets was designed to make it easy for any image optimization service to build a service on top of Astro.

¥What is an Image Service?

Astro 提供两种类型的图片服务:本地和外部。

¥Astro provides two types of image services: Local and External.

  • 本地服务在静态站点构建时直接处理图片转换,或在开发模式和 SSR 的运行时处理图片转换。这些通常是 Sharp、ImageMagick 或 Squoosh 等库的封装。在开发模式和 SSR 中,本地服务使用 API 端点来进行转换。

  • 外部服务指向 URL,可以添加对 Cloudinary、Vercel 或任何符合 RIAPI 的服务器等服务的支持。

使用图片服务 API 进行构建

Section titled 使用图片服务 API 进行构建

¥Building using the Image Services API

服务定义采用具有各种所需方法 (“hooks”) 的导出默认对象的形式。

¥Service definitions take the shape of an exported default object with various required methods (“hooks”).

外部服务提供指向输出 <img> 标记的 srcgetURL()

¥External services provide a getURL() that points to the src of the output <img> tag.

本地服务提供 transform() 方法来对图片执行转换,以及 getURL()parseURL() 方法以使用端点进行开发模式和 SSR。

¥Local services provide a transform() method to perform transformations on your image, and getURL() and parseURL() methods to use an endpoint for dev mode and SSR.

两种类型的服务都可以提供 getHTMLAttributes() 来确定输出 <img>validateOptions() 的其他属性,以验证和增强传递的选项。

¥Both types of services can provide getHTMLAttributes() to determine the other attributes of the output <img> and validateOptions() to validate and augment the passed options.

¥External Services

外部服务指向要用作最终 <img> 标记的 src 属性的远程 URL。该远程 URL 负责下载、转换和返回图片。

¥An external service points to a remote URL to be used as the src attribute of the final <img> tag. This remote URL is responsible for downloading, transforming, and returning the image.

import type { ExternalImageService, ImageTransform, AstroConfig } from "astro";
const service: ExternalImageService = {
validateOptions(options: ImageTransform, imageConfig: AstroConfig['image']) {
const serviceConfig = imageConfig.service.config;
// Enforce the user set max width.
if (options.width > serviceConfig.maxWidth) {
console.warn(`Image width ${options.width} exceeds max width ${serviceConfig.maxWidth}. Falling back to max width.`);
options.width = serviceConfig.maxWidth;
}
return options;
},
getURL(options, imageConfig) {
return `https://mysupercdn.com/${options.src}?q=${options.quality}&w=${options.width}&h=${options.height}`;
},
getHTMLAttributes(options, imageConfig) {
const { src, format, quality, ...attributes } = options;
return {
...attributes,
loading: options.loading ?? 'lazy',
decoding: options.decoding ?? 'async',
};
}
};
export default service;

¥Local Services

要创建你自己的本地服务,你可以指向 内置端点 (/_image),也可以另外创建你自己的可以调用服务方法的端点。

¥To create your own local service, you can point to the built-in endpoint (/_image), or you can additionally create your own endpoint that can call the service’s methods.

import type { LocalImageService, AstroConfig } from "astro";
const service: LocalImageService = {
getURL(options: ImageTransform, imageConfig: AstroConfig['image']) {
const searchParams = new URLSearchParams();
searchParams.append('href', typeof options.src === "string" ? options.src : options.src.src);
options.width && searchParams.append('w', options.width.toString());
options.height && searchParams.append('h', options.height.toString());
options.quality && searchParams.append('q', options.quality.toString());
options.format && searchParams.append('f', options.format);
return `/my_custom_endpoint_that_transforms_images?${searchParams}`;
// Or use the built-in endpoint, which will call your parseURL and transform functions:
// return `/_image?${searchParams}`;
},
parseURL(url: URL, imageConfig) {
return {
src: params.get('href')!,
width: params.has('w') ? parseInt(params.get('w')!) : undefined,
height: params.has('h') ? parseInt(params.get('h')!) : undefined,
format: params.get('f'),
quality: params.get('q'),
};
},
transform(buffer: Uint8Array, options: { src: string, [key: string]: any }, imageConfig): { data: Uint8Array, format: OutputFormat } {
const { buffer } = mySuperLibraryThatEncodesImages(options);
return {
data: buffer,
format: options.format,
};
},
getHTMLAttributes(options, imageConfig) {
let targetWidth = options.width;
let targetHeight = options.height;
if (typeof options.src === "object") {
const aspectRatio = options.src.width / options.src.height;
if (targetHeight && !targetWidth) {
targetWidth = Math.round(targetHeight * aspectRatio);
} else if (targetWidth && !targetHeight) {
targetHeight = Math.round(targetWidth / aspectRatio);
}
}
const { src, width, height, format, quality, ...attributes } = options;
return {
...attributes,
width: targetWidth,
height: targetHeight,
loading: attributes.loading ?? 'lazy',
decoding: attributes.decoding ?? 'async',
};
},
propertiesToHash: ['src', 'width', 'height', 'format', 'quality'],
};
export default service;

在静态站点和预渲染路由的构建时,<Image />getImage(options) 都会调用 transform() 函数。它们分别通过组件属性或 options 参数传递选项。转换后的图片将构建到 dist/_astro 文件夹中。它们的文件名将包含传递给 propertiesToHash 的属性的哈希值。此属性是可选的,默认为 ['src', 'width', 'height', 'format', 'quality']。如果你的自定义图片服务有更多更改生成图片的选项,请将这些选项添加到数组中。

¥At build time for static sites and pre-rendered routes, both <Image /> and getImage(options) call the transform() function. They pass options either through component attributes or an options argument, respectively. The transformed images will be built to a dist/_astro folder. Their file names will contain a hash of the properties passed to propertiesToHash. This property is optional and will default to ['src', 'width', 'height', 'format', 'quality']. If your custom image service has more options that change the generated images, add these to the array.

在开发模式和 SSR 模式下,Astro 并不提前知道哪些图片需要优化。Astro 使用 GET 端点(默认为 /_image)在运行时处理图片。<Image />getImage() 将其选项传递给 getURL(),后者将返回端点 URL。然后,端点调用 parseURL() 并将结果属性传递给 transform()

¥In dev mode and SSR mode, Astro doesn’t know ahead of time which images need to be optimized. Astro uses a GET endpoint (by default, /_image) to process the images at runtime. <Image /> and getImage() pass their options to getURL(), which will return the endpoint URL. Then, the endpoint calls parseURL() and passes the resulting properties to transform().

获取配置图片服务和图片配置

Section titled 获取配置图片服务和图片配置

¥getConfiguredImageService & imageConfig

如果你将自己的端点实现为 Astro 端点,则可以使用 getConfiguredImageServiceimageConfig 调用服务的 parseURLtransform 方法并提供图片配置。

¥If you implement your own endpoint as an Astro endpoint, you can use getConfiguredImageService and imageConfig to call your service’s parseURL and transform methods and provide the image config.

要访问图片服务配置(image.service.config),你可以使用 imageConfig.service.config

¥To access the image service config (image.service.config), you can use imageConfig.service.config.

src/api/my_custom_endpoint_that_transforms_images.ts
import type { APIRoute } from "astro";
import { getConfiguredImageService, imageConfig } from 'astro:assets';
export const GET: APIRoute = async ({ request }) => {
const imageService = await getConfiguredImageService();
const imageTransform = imageService.parseURL(new URL(request.url), imageConfig);
// ... fetch the image from imageTransform.src and store it in inputBuffer
const { data, format } = await imageService.transform(inputBuffer, imageTransform, imageConfig);
return new Response(data, {
status: 200,
headers: {
'Content-Type': mime.getType(format) || ''
}
}
);
}

查看内置端点 为完整示例。

¥See the built-in endpoint for a full example.

¥Hooks

本地和外部服务所需

¥Required for local and external services

getURL(options: ImageTransform, imageConfig: AstroConfig['image']): string

对于本地服务,此钩子返回生成图片的端点的 URL(在 SSR 和开发模式下)。在构建期间不使用它。getURL() 指向的本地端点可以同时调用 parseURL()transform()

¥For local services, this hook returns the URL of the endpoint that generates your image (in SSR and dev mode). It is unused during build. The local endpoint that getURL() points to may call both parseURL() and transform().

对于外部服务,此钩子返回图片的最终 URL。

¥For external services, this hook returns the final URL of the image.

对于这两种类型的服务,options 是用户作为 <Image /> 组件的属性或作为 getImage() 的选项传递的属性。它们属于以下类型:

¥For both types of services, options are the properties passed by the user as attributes of the <Image /> component or as options to getImage(). They are of the following type:

export type ImageTransform = {
// ESM imported images | remote/public image paths
src: ImageMetadata | string;
width?: number;
height?: number;
widths?: number[] | undefined;
densities?: (number | `${number}x`)[] | undefined;
quality?: ImageQuality;
format?: OutputFormat;
alt?: string;
[key: string]: any;
};

本地服务所需;不适用于外部服务

¥Required for local services; unavailable for external services

parseURL(url: URL, imageConfig: AstroConfig['image']): { src: string, [key: string]: any}

该钩子将 getURL() 生成的 URL 解析回具有供 transform 使用的不同属性的对象(在 SSR 和开发模式下)。在构建期间不使用它。

¥This hook parses the generated URLs by getURL() back into an object with the different properties to be used by transform (in SSR and dev mode). It is unused during build.

仅本地服务所需;不适用于外部服务

¥Required for local services only; unavailable for external services

transform(buffer: Uint8Array, options: { src: string, [key: string]: any }, imageConfig: AstroConfig['image']): { data: Uint8Array, format: OutputFormat }

该钩子转换并返回图片,并在构建过程中被调用以创建最终的资源文件。

¥This hook transforms and returns the image and is called during the build to create the final asset files.

你必须返回 format 以确保在 SSR 和开发模式下向用户提供正确的 MIME 类型。

¥You must return a format to ensure that the proper MIME type is served to users in SSR and development mode.

本地和外部服务可选

¥Optional for both local and external services

getHTMLAttributes(options: ImageTransform, imageConfig: AstroConfig['image']): Record<string, any>

该钩子根据用户传递的参数 (options) 返回用于将图片渲染为 HTML 的所有附加属性。

¥This hook returns all additional attributes used to render the image as HTML, based on the parameters passed by the user (options).

Added in: astro@3.3.0

对于本地和外部服务都是可选的。

¥Optional for both local and external services.

getSrcSet?: (options: ImageTransform, imageConfig: AstroConfig['image']): SrcSetValue[] | Promise<SrcSetValue[]>;

该钩子生成指定图片的多个变体,例如,在 <img><picture>source 上生成 srcset 属性。

¥This hook generates multiple variants of the specified image, for example, to generate a srcset attribute on an <img> or <picture>’s source.

该钩子返回具有以下属性的对象数组:

¥This hook returns an array of objects with the following properties:

export type SrcSetValue = {
transform: ImageTransform;
descriptor?: string;
attributes?: Record<string, any>;
};

本地和外部服务可选

¥Optional for both local and external services

validateOptions(options: ImageTransform, imageConfig: AstroConfig['image']): ImageTransform

该钩子允许你验证和增强用户传递的选项。这对于设置默认选项或告诉用户需要参数非常有用。

¥This hook allows you to validate and augment the options passed by the user. This is useful for setting default options, or telling the user that a parameter is required.

查看 validateOptions() 如何在 Astro 内置服务中使用

¥See how validateOptions() is used in Astro built-in services.

¥User configuration

配置要在 astro.config.mjs 中使用的图片服务。配置采用以下形式:

¥Configure the image service to use in astro.config.mjs. The config takes the following form:

astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({
image: {
service: {
entrypoint: "your-entrypoint", // 'astro/assets/services/squoosh' | 'astro/assets/services/sharp' | string,
config: {
// ... service-specific config. Optional.
}
}
},
});
Astro 中文网 - 粤ICP备13048890号