import { Image as ExpoImage, type ImageProps as ExpoImageProps } from 'expo-image' import React, { forwardRef, memo, useMemo } from 'react' import tw from 'twrnc' interface ImgProps extends ExpoImageProps { className?: string src?: string | number width?: number isWebP?: boolean errorSource?: string | number isCompression?: boolean /** 自定义缓存键,用于需要重定向的 URL */ cacheKey?: string } // ExpoImage.clearDiskCache() // ExpoImage.clearMemoryCache() // cloudflare 图片优化服务示例地址 const ImageOrigin = `https://bowong.cc/cdn-cgi/image/width=128,quality=75,format=webp/https://cdn.roasmax.cn/material/b59b75841c484d8bafec9c5636930b69.webp` const Img = forwardRef((props, ref) => { const { className = '', style = {}, src, errorSource, source: propSource, cacheKey, width = 256, isCompression = false, isWebP = true, ...reset } = props const imageStyle = tw`${className}` // 静态图全部压缩jpg const compressionUrl = useMemo(() => { const f = isWebP ? 'webp' : 'jpg' return `https://bowong.cc/cdn-cgi/image/width=${width},quality=75,format=${f}/${src}` }, [width, isWebP, src]) // 判断是否为网络图片 const isNetworkImage = (uri: string | number): boolean => { if (typeof uri !== 'string') return false return uri.startsWith('http://') || uri.startsWith('https://') } // 构建图片源 const imageSource = useMemo(() => { // 如果提供了source属性,优先使用 if (propSource) return propSource if (!src) return undefined if (typeof src === 'number') { // 本地图片资源(require导入的资源ID) return src } else { // 网络图片或本地文件路径 if (isNetworkImage(src)) { const finalUrl = isCompression ? compressionUrl : src // console.log('finalUrl-------------', finalUrl) return { uri: finalUrl, cacheKey: cacheKey || finalUrl, } } else { // 本地文件路径 return { uri: src } } } }, [src, propSource, cacheKey, isCompression, compressionUrl]) const imgProps = { style: [style, imageStyle], ref, source: imageSource, // 使用 disk 缓存策略,减少内存占用 cachePolicy: 'disk' as const, // 添加内存缓存上限,当内存紧张时优先释放 recyclingKey: typeof src === 'string' ? src : undefined, errorSource, transition: { duration: 200, effect: 'cross-dissolve' as const }, ...reset, } return // return }) Img.displayName = 'Img' export default memo(Img)