This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
Expo 图片
一个跨平台且高性能的 React 组件,用于加载和渲染图片。
expo-image 是一个跨平台的 React 组件,用于加载和渲染图像。
主要功能:
- 专为速度而设计
- 支持多种图像格式(包括动画格式)
- 磁盘和内存缓存
- 支持 BlurHash 和 ThumbHash——图像占位符的紧凑表示形式
- 当来源发生变化时在图像之间进行过渡(不再闪烁!)
- 实现了 CSS 的
object-fit和object-position属性(参见contentFit和contentPosition属性) - 底层使用高性能的
SDWebImage和Glide
支持的图像格式
† 在 iOS 上,系统 SVG 解码器无法处理所有有效路径。如果椭圆弧命令(
A或a)包含多个参数集,并且large-arc-flag和sweep-flag的值紧凑排列,可能会导致渲染失真或完全无法渲染。大多数 SVG 压缩工具都会生成这种紧凑形式,例如a6 6 0 0111.573-2.226 3.75 3.75 0 014.133 4.303。要修复文件,请用空格分隔这两个标志(a6 6 0 0 1 11.573 -2.226 3.75 3.75 0 0 1 4.133 4.303),或为每条弧使用单独的命令。若要获得更广泛的 SVG 支持,请使用react-native-svg,它可以正确渲染这些路径。
安装
If you are installing this in an existing React Native app, make sure to install expo in your project.
在应用配置中配置
你可以使用 expo-image 的配置插件配置构建时设置。将该插件添加到 app.json 或 app.config.js 中的 plugins 数组,然后重新构建原生项目。
Example app.json with config plugin
Configurable properties
Are you using this library in an existing React Native app?
如果你未使用连续原生生成(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[ayj[fQa{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', }, });
使用原生资源中的图像
Xcode 资源目录或 Android drawable 资源中打包的图像可以通过名称加载,例如
source={{ uri: 'app_icon' }}。省略文件扩展名,并手动提供图像尺寸:
import { Image } from 'expo-image'; export default function AppIcon() { return <Image source={{ uri: 'app_icon' }} style={{ width: 40, height: 40 }} />; }
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.
boolean • Default: falseA Boolean value indicating whether the accessibility elements contained within the image are hidden from the screen reader.
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: `'lazy'` (when `responsivePolicy` is `'static'`, otherwise `'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.
Defaults to 'lazy' when responsivePolicy is 'static' (the default policy), because the
sizes="auto" source selection used by static only takes effect on lazily-loaded images.
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 | string[] | ImageSource | SharedRef<'image', Record<never, never>> | ImageSource[] | 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: 'center' | 'cover' | 'contain' | 'repeat' | '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 source is selected by the browser from a generated srcset/sizes pair. Works with static rendering.
The generated sizes leads with the auto keyword, so supporting browsers select the source from the image's rendered layout size.
This requires the image to be lazily loaded, which is why static defaults loading to 'lazy' (pass loading="eager" to opt out,
in which case sizes="auto" is ignored). For browsers that don't yet support sizes="auto", sizes falls back to any per-source
breakpoints (only emitted for sources that set the deprecated webMaxViewportWidth) and finally to 100vw.
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: 'static' | 'live' | 'initial'
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 | string[] | string & undefined | ImageSource | SharedRef<'image', Record<never, never>> | ImageSource[] | sf:<symbol>
unionValues for the CSS custom properties
that an SVG source refers to with var(). Each entry is substituted into the document before it
is parsed, so the image stays a vector, unlike an SVG tinted with tintColor on iOS.
Because the substitution happens on the document itself, different parts of one SVG can be given different values, so a single document can be tinted with several colors.
Values are not limited to colors. Anything a custom property stands in for, such as
stroke-width or opacity, is substituted the same way. Keys include the leading --.
Values are inserted as written and cannot refer to other custom properties: a value such as
'var(--other)' is not resolved. Reference a paint server the document defines with url(#id).
A property that is not supplied falls back to the value declared inside its own var(). When
there is no fallback, the declaration is dropped and the renderer applies its own default.
An SVG that uses var() is rendered with its fallbacks even when this prop is not set. A
document authored for the browser looks the same in the app.
Note: Colors must be values the SVG itself understands, such as
'#ff0000'or'red'. React Native color descriptors likePlatformColorare not resolved.
Note:
tintColoris applied on top of the substituted document. It floods every pixel with a single color, so color values are hidden by it while other values, such as widths or opacities, still take effect. On iOS the image is rasterized in that case, as withtintColoralone.
Has no effect on sources that aren't SVG.
Example
// house.svg contains fill="var(--roof, #888)" and fill="var(--wall, #ccc)" <Image source={require('./house.svg')} svgVariables={{ '--roof': '#ee3333', '--wall': '#3399ff', '--stroke-width': 2 }} />
Acceptable values are: Record<string, string | number> | null
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.
Some animated WebP files also decode very slowly with Apple's codec, which can make the image take a long time to appear and keep a CPU core busy while it loads.
If you run into that, try setting this prop to false to switch to libwebp instead.
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.
Configures the image cache. This allows you to manage the cache eviction policy.
voidAsynchronously 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.
Loads an image from the given source to memory and resolves to an object that references the native image instance.
Promise<ImageRef>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.
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.
Asynchronously reads an image stored in the cache under the given cache key and resolves to
an ImageRef that can be passed straight to the source of an
image view. Resolves to null when no image is cached for the key.
Promise<ImageRef | null>A promise resolving to the cached image reference, or null if it isn't cached.
Asynchronously writes a local image to the disk cache under the given cache key,
without fetching it over the network. Use this to seed the cache from an image you
already have on the device, for example one returned by expo-image-picker or
downloaded with expo-file-system. A later image load that uses the same cacheKey
in its source will then be served straight from the cache.
Promise<void>A promise that resolves once the image has been written to the disk cache.
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
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 either
maxWidthormaxHeightoption 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.
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:
Or object shaped as below:
Or object shaped as below:
Or object shaped as below:
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'
An object that describes the smooth transition when switching the image source.
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
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 包。
接下来,从已安装的包中导入所有必需的函数,并初始化 multer:
// Multer is a middleware for handling `multipart/form-data`. const multer = require('multer'); // Sharp allows you to receive a data buffer from the uploaded image. const sharp = require('sharp'); // Import the encode function from the blurhash package. const { encode } = require('blurhash'); // Initialize `multer`. const upload = multer();
假设 app 是一个保存 Express 服务器引用的变量,就可以创建一个接收图像并返回包含生成的 blurhash 的 JSON 响应的端点。
app.post('/blurhash', upload.single('image'), async (req, res) => { const { file } = req; // If the file is not available we're returning with error. if (file === null) { res.status(400).json({ message: 'Image is missing' }); return; } // Users can specify number of components in each axes. const componentX = req.body.componentX ?? 4; const componentY = req.body.componentY ?? 3; // We're converting provided image to a byte buffer. // Sharp currently supports multiple common formats like JPEG, PNG, WebP, GIF, and 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 时效果最佳,但生成哈希可能需要更长时间。
与使用 JavaScript 的方法类似,可以使用各种语言和服务器技术生成 blurhash。关键步骤是找到适用于所选语言的编码器,通常可以在 woltapp/blurhash 仓库中找到。找到编码器后,你需要获取图像的表示形式。一些库使用默认图像类(例如,Swift 实现使用 UIImage)。其他情况下,则需要提供原始字节数据。请务必查看编码器文档,确认其所需的数据格式。
处理原始字节数据时,请确保包含 alpha 通道(每个像素由红、绿、蓝和 alpha 值表示)。否则会导致“width and height must match the pixels array”等错误。