Expo 图像
一个跨平台且高性能的 React 组件,用于加载和渲染图像。
For the complete documentation index, see llms.txt. Use this Use this file to discover all available pages.
expo-image 是一个跨平台 React 组件,用于加载和渲染图像。
主要特性:
- 以速度为设计目标
- 支持多种图像格式(包括动画格式)
- 磁盘和内存缓存
- 支持 BlurHash 和 ThumbHash —— 图像占位符的紧凑表示
- 在源图像发生变化时可在图片之间平滑过渡(不再闪烁!)
- 实现了 CSS 的
object-fit和object-position属性(参见contentFit和contentPosition属性) - 底层使用高性能的
SDWebImage和Glide
支持的图像格式
| 格式 | Android | iOS | Web |
|---|---|---|---|
| WebP | |||
| PNG / APNG | |||
| AVIF | |||
| HEIC | 尚未采用 | ||
| JPEG | |||
| GIF | |||
| SVG | |||
| ICO | |||
| ICNS | |||
| PSD (复合预览) |
安装
- npx expo install expo-imageIf you are installing this in an existing React Native app, make sure to install expo in your project.
在 app 配置中的配置
你可以使用 expo-image 的 配置插件 来配置其构建时设置。将该插件添加到 app.json 或 app.config.js 中的 plugins 数组里,然后重新构建原生项目。
Example app.json with config plugin
{ "expo": { "plugins": [ [ "expo-image", { "disableLibdav1d": true } ] ] } }
Configurable properties
| Name | Default | Description |
|---|---|---|
disableLibdav1d | false | Only for: iOS 当为 |
Are you using this library in an existing React Native app?
如果你没有使用 Continuous Native Generation (CNG)
或者你正在手动使用原生 ios 项目,那么在运行 pod install 之前设置 shell 环境变量
EXPO_IMAGE_DISABLE_LIBDAV1D=1 以达到相同效果。
或者,你也可以在 Podfile 顶部添加 ENV['EXPO_IMAGE_DISABLE_LIBDAV1D'] ||= '0'。
用法
import { Image } from 'expo-image'; import { StyleSheet, View } from 'react-native'; const blurhash = '|rF?hV%2WCj[ayj[a|j[az_NaeWBj@ayfRayfQfQM{M|azj[azf6fQfQfQIpWXofj[ayj[j[fQayWCoeoeaya}j[ayfQa{oLj?j[WVj[ayayj[fQoff7azayj[ayj[j[ayofayayayj[fQj[ayayj[ayfjj[j[ayjuayj['; export default function App() { return ( <View style={styles.container}> <Image style={styles.image} source="https://picsum.photos/seed/696/3000/2000" placeholder={{ blurhash }} contentFit="cover" transition={1000} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, image: { flex: 1, width: '100%', backgroundColor: '#0553', }, });
API
import { Image } from 'expo-image';
Components
Type: React.PureComponent<ImageProps>
Some props are from React Native Image that Expo Image supports (more or less) for easier migration, but all of them are deprecated and might be removed in the future.
string • Default: undefinedThe text that's read by the screen reader when the user interacts with the image. Sets the alt tag on web which is used for web crawlers and link traversal.
boolean • Default: falseWhen true, indicates that the view is an accessibility element. When a view is an accessibility element, it groups its children into a single selectable component.
On Android, the accessible property will be translated into the native isScreenReaderFocusable,
so it's only affecting the screen readers behaviour.
boolean • Default: trueWhether the image should be downscaled to match the size of the view container. Turning off this functionality could negatively impact the application's performance, particularly when working with large assets. However, it would result in smoother image resizing, and end-users would always have access to the highest possible asset quality.
Downscaling is never used when the contentFit prop is set to none or fill.
string • Default: undefinedThe text that's read by the screen reader when the user interacts with the image. Sets the alt tag on web which is used for web crawlers and link traversal. Is an alias for accessibilityLabel.
boolean • Default: trueDetermines if an image should automatically begin playing if it is an animated image.
number • Default: 0The radius of the blur in points, 0 means no blur effect.
This effect is not applied to placeholders.
union • Default: 'disk'Determines whether to cache the image and where: on the disk, in the memory or both.
-
'none'- Image is not cached at all. -
'disk'- Image is queried from the disk cache if exists, otherwise it's downloaded and then stored on the disk. -
'memory'- Image is cached in memory. Might be useful when you render a high-resolution picture many times. Memory cache may be purged very quickly to prevent high memory usage and the risk of out of memory exceptions. -
'memory-disk'- Image is cached in memory, but with a fallback to the disk cache.
Acceptable values are: 'none' | 'disk' | 'memory' | 'memory-disk' | null
ImageContentFit • Default: 'cover'Determines how the image should be resized to fit its container. This property tells the image to fill the container
in a variety of ways; such as "preserve that aspect ratio" or "stretch up and take up as much space as possible".
It mirrors the CSS object-fit property.
-
'cover'- The image is sized to maintain its aspect ratio while filling the container box. If the image's aspect ratio does not match the aspect ratio of its box, then the object will be clipped to fit. -
'contain'- The image is scaled down or up to maintain its aspect ratio while fitting within the container box. -
'fill'- The image is sized to entirely fill the container box. If necessary, the image will be stretched or squished to fit. -
'none'- The image is not resized and is centered by default. When specified, the exact position can be controlled withcontentPositionprop. -
'scale-down'- The image is sized as ifnoneorcontainwere specified, whichever would result in a smaller concrete image size.
ImageContentPosition • Default: 'center'It is used together with contentFit to specify how the image should be positioned with x/y coordinates inside its own container.
An equivalent of the CSS object-position property.
ImageDecodeFormat • Default: 'argb'The format in which the image data should be decoded. It's not guaranteed that the platform will use the specified format.
-
'argb'- The image is decoded into a 32-bit color space with alpha channel (https://developer.android.com/reference/android/graphics/Bitmap.Config#ARGB_8888). -
'rgb'- The image is decoded into a 16-bit color space without alpha channel (https://developer.android.com/reference/android/graphics/Bitmap.Config#RGB_565).
Deprecated: Provides compatibility for
defaultSourcefrom React Native Image. Useplaceholderprop instead.
unionAcceptable values are: ImageSource | null
boolean • Default: undefinedWhether the img element is draggable on web.
boolean • Default: falseEnables Live Text interaction with the image. Check official Apple documentation for more details.
boolean • Default: falseForce early resizing of the image to match the container size.
This option helps to reduce the memory usage of the image view, especially when the image is larger than the container.
It may affect the resizeType and contentPosition properties when the image view is resized dynamically.
Deprecated: Provides compatibility for
fadeDurationfrom React Native Image. Instead usetransitionwith the provided duration.
numberboolean • Default: falseWhether this View should be focusable with a non-touch input device and receive focus with a hardware keyboard.
string • Default: 'eager'Sets the HTML loading attribute on the <img> element.
Has no effect on native platforms.
'lazy'- Defers loading until the image is near the viewport.'eager'- Loads the image immediately.
Acceptable values are: 'lazy' | 'eager'
Deprecated: Provides compatibility for
loadingIndicatorSourcefrom React Native Image. Useplaceholderprop instead.
unionAcceptable values are: ImageSource | null
() => voidCalled when the image view successfully rendered the source image.
(event: ImageErrorEventData) => voidCalled on an image fetching error.
(event: ImageLoadEventData) => voidCalled when the image load completes successfully.
() => voidCalled when the image load either succeeds or fails.
(event: ImageProgressEventData) => voidCalled when the image is loading. Can be called multiple times before the image has finished loading. The event object provides details on how many bytes were loaded so far and what's the expected total size.
unionAn image to display while loading the proper image and no image has been displayed yet or the source is unset.
Note: The default value for placeholder's content fit is 'scale-down', which differs from the source image's default value. Using a lower-resolution placeholder may cause flickering due to scaling differences between it and the final image. To prevent this, you can set the
placeholderContentFitto match thecontentFitvalue.
Acceptable values are: string | number | ImageSource | SharedRef<'image', Record<never, never>> | ImageSource[] | string[] | null
ImageContentFit • Default: 'scale-down'Determines how the placeholder should be resized to fit its container. Available resize modes are the same as for the contentFit prop.
boolean • Default: falseControls whether the image view can leverage the extended dynamic range (EDR). Use this prop if you want to support high dynamic range (HDR) images, otherwise all images are rendered as standard dynamic range (SDR).
union • Default: 'normal'Priorities for completing loads. If more than one load is queued at a time, the load with the higher priority will be started first. Priorities are considered best effort, there are no guarantees about the order in which loads will start or finish.
Acceptable values are: 'normal' | 'low' | 'high' | null
union • Default: nullChanging this prop resets the image view content to blank or a placeholder before loading and rendering the final image. This is especially useful for any kinds of recycling views like FlashList to prevent showing the previous source before the new one fully loads.
Acceptable values are: string | null
Deprecated: Provides compatibility for
resizeModefrom React Native Image. Note that"repeat"option is not supported at all. Use the more powerfulcontentFitandcontentPositionprops instead.
stringAcceptable values are: 'cover' | 'contain' | 'repeat' | 'center' | 'stretch'
string • Default: 'static'Controls the selection of the image source based on the container or viewport size on the web.
If set to 'static', the browser selects the correct source based on user's viewport width. Works with static rendering.
Make sure to set the 'webMaxViewportWidth' property on each source for best results.
For example, if an image occupies 1/3 of the screen width, set the 'webMaxViewportWidth' to 3x the image width.
The source with the largest 'webMaxViewportWidth' is used even for larger viewports.
If set to 'initial', the component will select the correct source during mount based on container size. Does not work with static rendering.
If set to 'live', the component will select the correct source on every resize based on container size. Does not work with static rendering.
Acceptable values are: 'live' | 'initial' | 'static'
unionSF Symbol effect animations. Can be a single effect string, an effect object, or an array of effect strings and/or objects.
Example
// Single effect as string sfEffect="bounce" // Single effect as object with options sfEffect={{ effect: "bounce", repeat: -1, scope: "by-layer" }} // Array of mixed strings and objects sfEffect={["bounce", { effect: "pulse", repeat: -1 }]}
Acceptable values are: SFSymbolEffect | null
unionThe image source, either a remote URL, a local file resource or a number that is the result of the require() function.
When provided as an array of sources, the source that fits best into the container size and is closest to the screen scale
will be chosen. In this case it is important to provide width, height and scale properties.
For SF Symbols (iOS), use the sf: prefix followed by the symbol name, for example, sf:star.fill.
Note: For the complete list of SF Symbols, see Apple's SF Symbols catalog or the
sf-symbols-typescriptlibrary documentation.
Acceptable values are: number | ImageSource | string & undefined | SharedRef<'image', Record<never, never>> | ImageSource[] | string[] | sf:<symbol>
union • Default: nullA color used to tint template images (a bitmap image where only the opacity matters). The color is applied to every non-transparent pixel, causing the image's shape to adopt that color. This effect is not applied to placeholders.
Note that useImage options parameter also has a tintColor field.
When you have a useImage as a source use its tintColor instead.
Acceptable values are: string | null
unionDescribes how the image view should transition the contents when switching the image source.
If provided as a number, it is the duration in milliseconds of the 'cross-dissolve' effect.
Acceptable values are: number | ImageTransition | null
boolean • Default: trueWhether to use the Apple's default WebP codec.
Set this prop to false to use the official standard-compliant libwebp codec for WebP images.
The default implementation from Apple is faster and uses less memory but may render animated images with incorrect blending or play them at the wrong framerate.
Type: React.Element<ImageBackgroundProps>
It allows you to use an image as a background while rendering other content on top of it.
It extends all Image props but provides separate styling controls for the container and the background image itself.
Inherited Props
Omit<ImageProps, 'style'>
Static Methods
Asynchronously clears all images from the disk cache.
Promise<boolean>A promise resolving to true when the operation succeeds.
It may resolve to false on Android when the activity is no longer available.
Resolves to false on Web.
Asynchronously clears all images stored in memory.
Promise<boolean>A promise resolving to true when the operation succeeds.
It may resolve to false on Android when the activity is no longer available.
Resolves to false on Web.
| Parameter | Type | Description |
|---|---|---|
| config | ImageCacheConfig | The cache configuration. |
Configures the image cache. This allows you to manage the cache eviction policy.
void| Parameter | Type | Description |
|---|---|---|
| source | string | ImageRef | The image source, either a URL (string) or an ImageRef |
| numberOfComponents | [number, number] | {
height: number,
width: number
} | The number of components to encode the blurhash with.
Must be between 1 and 9. Defaults to |
| Parameter | Type | Description |
|---|---|---|
| source | string | ImageRef | The image source, either a URL (string) or an ImageRef |
| Parameter | Type | Description |
|---|---|---|
| cacheKey | string | The cache key for the requested image. Unless you have set a custom cache key, this will be the source URL of the image. |
Asynchronously checks if an image exists in the disk cache and resolves to the path of the cached image if it does.
Promise<string | null>A promise resolving to the path of the cached image. It will resolve
to null if the image does not exist in the cache.
| Parameter | Type |
|---|---|
| source | string | number | ImageSource |
| options(optional) | ImageLoadOptions |
Loads an image from the given source to memory and resolves to an object that references the native image instance.
Promise<ImageRef>| Parameter | Type | Description |
|---|---|---|
| urls | string | string[] | A URL string or an array of URLs of images to prefetch. |
| cachePolicy(optional) | 'disk' | 'memory' | 'memory-disk' | The cache policy for prefetched images. |
Preloads images at the given URLs that can be later used in the image view.
Preloaded images are cached to the memory and disk by default, so make sure
to use disk (default) or memory-disk cache policy.
Promise<boolean>A promise resolving to true as soon as all images have been
successfully prefetched. If an image fails to be prefetched, the promise
will immediately resolve to false regardless of whether other images have
finished prefetching.
| Parameter | Type | Description |
|---|---|---|
| urls | string | string[] | A URL string or an array of URLs of images to prefetch. |
| options(optional) | ImagePrefetchOptions | Options for prefetching images. |
Preloads images at the given URLs that can be later used in the image view.
Preloaded images are cached to the memory and disk by default, so make sure
to use disk (default) or memory-disk cache policy.
Promise<boolean>A promise resolving to true as soon as all images have been
successfully prefetched. If an image fails to be prefetched, the promise
will immediately resolve to false regardless of whether other images have
finished prefetching.
Component Methods
Prevents the resource from being reloaded by locking it.
Promise<void>Reloads the resource, ignoring lock.
Promise<void>Asynchronously starts playback of the view's image if it is animated.
Promise<void>Asynchronously stops the playback of the view's image if it is animated.
Promise<void>Releases the lock on the resource, allowing it to be reloaded.
Promise<void>Hooks
| Parameter | Type |
|---|---|
| source | string | number | ImageSource |
| options(optional) | ImageLoadOptions |
| dependencies(optional) | DependencyList |
A hook that loads an image from the given source and returns a reference
to the native image instance, or null until the first image is successfully loaded.
It loads a new image every time the uri of the provided source changes.
To trigger reloads in some other scenarios, you can provide an additional dependency list.
Avoid using this hook for large images without specifying size constraints, as it may cause crashes due to excessive memory usage. It is recommended to use eithermaxWidthormaxHeightoption to scale down the image appropriately for your use case.
ImageRef | nullExample
import { useImage, Image } from 'expo-image'; import { Text } from 'react-native'; export default function MyImage() { const image = useImage('https://picsum.photos/1000/800', { maxWidth: 800, onError(error, retry) { console.error('Loading failed:', error.message); } }); if (!image) { return <Text>Image is loading...</Text>; } return <Image source={image} style={{ width: image.width / 2, height: image.height / 2 }} />; }
Classes
Type: Class extends SharedRef<'image'>
An object that is a reference to a native image instance – Drawable on Android and UIImage on iOS. Instances of this class can be passed as a source to the Image component in which case the image is rendered immediately since its native representation is already available in the memory.
ImageRef Properties
numberLogical height of the image. Multiply it by the value in the scale property to get the height in pixels.
booleanWhether the referenced image is an animated image.
unionMedia type (also known as MIME type) of the image, based on its format.
Returns null when the format is unknown or not supported.
Acceptable values are: string | null
numberOn iOS, if you load an image from a file whose name includes the @2x modifier, the scale is set to 2.0. All other images are assumed to have a scale factor of 1.0.
On Android, it calculates the scale based on the bitmap density divided by screen density.
On all platforms, if you multiply the logical size of the image by this value, you get the dimensions of the image in pixels.
Types
An object containing options for the configureCache function.
See SDImageCacheConfig for more information.
| Property | Type | Description |
|---|---|---|
| maxDiskSize(optional) | number | The maximum size of the disk cache, in bytes. Defaults to 0, which means there is no cache size limit. |
| maxMemoryCost(optional) | number | The maximum "total cost" of the in-memory image cache. The cost function is the bytes size held in memory, not simply the pixel count. For example, a typical ARGB8888 image uses 4 bytes (32 bits) per pixel. Defaults to 0, which means there is no memory cost limit. |
| maxMemoryCount(optional) | number | The maximum number of objects the in-memory image cache should hold. Defaults to 0, which means there is no memory count limit. |
Specifies the position of the image inside its container. One value controls the x-axis and the second value controls the y-axis.
Additionally, it supports stringified shorthand form that specifies the edges to which to align the image content:
'center', 'top', 'right', 'bottom', 'left', 'top center', 'top right', 'top left', 'right center', 'right top',
'right bottom', 'bottom center', 'bottom right', 'bottom left', 'left center', 'left top', 'left bottom'.
If only one keyword is provided, then the other dimension is set to 'center' ('50%'), so the image is placed in the middle of the specified edge.
As an example, 'top right' is the same as { top: 0, right: 0 } and 'bottom' is the same as { bottom: 0, left: '50%' }.
Type: ImageContentPositionString or object shaped as below:
| Property | Type | Description |
|---|---|---|
| right(optional) | ImageContentPositionValue | - |
| top(optional) | ImageContentPositionValue | - |
Or object shaped as below:
| Property | Type | Description |
|---|---|---|
| left(optional) | ImageContentPositionValue | - |
| top(optional) | ImageContentPositionValue | - |
Or object shaped as below:
| Property | Type | Description |
|---|---|---|
| bottom(optional) | ImageContentPositionValue | - |
| right(optional) | ImageContentPositionValue | - |
Or object shaped as below:
| Property | Type | Description |
|---|---|---|
| bottom(optional) | ImageContentPositionValue | - |
| left(optional) | ImageContentPositionValue | - |
Literal Type: union
A value that represents the relative position of a single axis.
If number, it is a distance in points (logical pixels) from the respective edge.
If string, it must be a percentage value where '100%' is the difference in size between the container and the image along the respective axis,
or 'center' which is an alias for '50%' that is the default value. You can read more regarding percentages on the MDN docs for
background-position that describes this concept well.
Acceptable values are: number | string | {number}% | {number} | 'center'
| Property | Type | Description |
|---|---|---|
| cacheType | 'none' | 'disk' | 'memory' | - |
| source | {
height: number,
isAnimated: boolean,
mediaType: string | null,
url: string,
width: number
} | - |
An object with options for the useImage hook.
| Property | Type | Description |
|---|---|---|
| maxHeight(optional) | number | If provided, the image will be automatically resized to not exceed this height in pixels, preserving its aspect ratio. |
| maxWidth(optional) | number | If provided, the image will be automatically resized to not exceed this width in pixels, preserving its aspect ratio. |
| tintColor(optional) | ColorValue | number | A color used to tint template images (a bitmap image where only the opacity matters). The color is applied to every non-transparent pixel, causing the image's shape to adopt that color. Default: null |
| onError(optional) | (error: Error, retry: () => void) => void | Function to call when the image has failed to load. In addition to the error, it also provides a function that retries loading the image. |
| Property | Type | Description |
|---|---|---|
| cachePolicy(optional) | 'disk' | 'memory-disk' | 'memory' | The cache policy for prefetched images. Default: 'memory-disk' |
| headers(optional) | Record<string, string> | A map of headers to use when prefetching the images. |
| Property | Type | Description |
|---|---|---|
| blurhash(optional) | string | A string used to generate the image When using the blurhash, you should also provide |
| cacheKey(optional) | string | The cache key used to query and store this specific image.
If not provided, the |
| headers(optional) | Record<string, string> | An object representing the HTTP headers to send along with the request for a remote image.
On web requires the |
| height(optional) | number | null | Can be specified if known at build time, in which case the value
will be used to set the default |
| isAnimated(optional) | boolean | Only for: Android iOS Whether the image is animated (an animated GIF or WebP for example). |
| thumbhash(optional) | string | A string used to generate the image For more information, see |
| uri(optional) | string | A string representing the resource identifier for the image, which could be an HTTPS address, a local file path, or the name of a static image resource. |
| webMaxViewportWidth(optional) | number | Only for: Web The max width of the viewport for which this source should be selected.
Has no effect if |
| width(optional) | number | null | Can be specified if known at build time, in which case the value
will be used to set the default |
An object that describes the smooth transition when switching the image source.
| Property | Type | Description |
|---|---|---|
| duration(optional) | number | The duration of the transition in milliseconds. Default: 0 |
| effect(optional) | 'cross-dissolve' | 'flip-from-top' | 'flip-from-right' | 'flip-from-bottom' | 'flip-from-left' | 'curl-up' | 'curl-down' | 'sf:replace' | 'sf:down-up' | 'sf:up-up' | 'sf:off-up' | null | An animation effect used for transition. Default: 'cross-dissolve'
On Android, only `'cross-dissolve'` is supported.
On Web, `'curl-up'` and `'curl-down'` effects are not supported.
For SF Symbols (iOS 17+), use the `sf:` effects to animate
when the symbol source changes:
- `'sf:replace'` - The symbol animates when replaced with another symbol.
- `'sf:down-up'` - New symbol slides in from bottom.
- `'sf:up-up'` - New symbol slides in from top.
- `'sf:off-up'` - Cross-dissolve transition between symbols.
For other SF Symbol animations (bounce, pulse, scale, and so on), use the `sfEffect` prop instead. |
| timing(optional) | 'ease-in-out' | 'ease-in' | 'ease-out' | 'linear' | Specifies the speed curve of the transition effect and how intermediate values are calculated. Default: 'ease-in-out' |
Literal Type: union
SF Symbol effect configuration. Can be a single effect string, an effect object, or an array of effect strings and/or objects.
Example
// Single effect as string sfEffect="bounce" // Single effect as object with options sfEffect={{ effect: "bounce", repeat: -1, scope: "by-layer" }} // Array of mixed strings and objects sfEffect={["bounce", { effect: "pulse", repeat: -1 }]}
Acceptable values are: SFSymbolEffectType | SFSymbolEffectObject
An object that describes an SF Symbol effect animation.
| Property | Type | Description |
|---|---|---|
| effect | SFSymbolEffectType | The type of SF Symbol effect animation.
For iOS 18+:
For iOS 26+:
|
| repeat(optional) | number | The number of times to repeat the effect.
Default: 0 |
| scope(optional) | 'by-layer' | 'whole-symbol' | null | Controls how the effect animates across symbol layers.
Default: undefined (uses system default) |
Literal Type: string
The type of SF Symbol effect animation.
Acceptable values are: 'bounce' | 'bounce/up' | 'bounce/down' | 'pulse' | 'variable-color' | 'variable-color/iterative' | 'variable-color/cumulative' | 'scale' | 'scale/up' | 'scale/down' | 'appear' | 'disappear' | 'wiggle' | 'rotate' | 'breathe' | 'draw/on' | 'draw/off'
在服务器上生成 blurhash
图像可以显著提升视觉体验,但由于文件较大,也可能会拖慢应用/页面的加载时间。为了解决这个问题,你可以使用 blurhash 算法创建占位图像,在延迟加载实际图片的同时提供更沉浸的体验。
本指南演示如何使用 JavaScript 和 Express.js 在后端为上传的图像创建 blurhash。相同的技术和原理也适用于其他语言和服务器技术。
首先安装一些依赖:用于处理 multipart 请求的 multer、用于将文件转换为数据缓冲区的 sharp,以及官方的 blurhash JavaScript 包。
- npm install multer sharp blurhash接下来,从已安装的包中导入所有必需的函数,并初始化 multer:
// Multer 是一个用于处理 `multipart/form-data` 的中间件。 const multer = require('multer'); // Sharp 允许你从上传的图像中接收数据缓冲区。 const sharp = require('sharp'); // 从 blurhash 包中导入 encode 函数。 const { encode } = require('blurhash'); // 初始化 `multer`。 const upload = multer();
假设 app 是持有 Express 服务器引用的变量,那么可以创建一个接收图像并返回包含生成的 blurhash 的 JSON 响应的端点。
app.post('/blurhash', upload.single('image'), async (req, res) => { const { file } = req; // 如果文件不可用,我们将返回错误。 if (file === null) { res.status(400).json({ message: 'Image is missing' }); return; } // 用户可以指定每个轴上的组件数量。 const componentX = req.body.componentX ?? 4; const componentY = req.body.componentY ?? 3; // 我们正在将提供的图像转换为字节缓冲区。 // Sharp 目前支持多种常见格式,如 JPEG、PNG、WebP、GIF 和 AVIF。 const { data, info } = await sharp(file.buffer).ensureAlpha().raw().toBuffer({ resolveWithObject: true, }); const blurhash = encode( new Uint8ClampedArray(data), info.width, info.height, componentX, componentY ); res.json({ blurhash }); });
此外,请求还可以包含两个参数:componentX 和 componentY,它们会传递给该算法。这些值可以在服务器上计算或硬编码,也可以由用户指定。不过,它们必须在 1 到 9 的范围内,并且长宽比应与上传的图像相近。值为 9 时效果最好,但生成哈希可能需要更长时间。
生成 blurhash 的过程可以通过多种语言和服务器技术实现,类似于使用 JavaScript 的方案。关键步骤是为你所选的语言找到一个编码器,这通常可以在 woltapp/blurhash 仓库中找到。拥有编码器后,你还需要获取图像的表示形式。有些库使用默认的图像类(例如,Swift 实现使用 UIImage)。在其他情况下,你需要提供原始字节数据。请务必查看编码器的文档,以确认所需的数据格式。
处理原始字节数据时,请确保存在 alpha 层(每个像素由红、绿、蓝和 alpha 值表示)。如果没有,会导致诸如“width and height must match the pixels array”之类的错误。