import * as ImageManipulator from 'expo-image-manipulator'; import { Image } from 'react-native'; // 压缩图片,自动等比缩放,最大边不超过 800 export const compressImage = async (uri: string, maxSize = 800): Promise<{ uri: string; file: File }> => { // 获取原图尺寸 const getImageSize = (uri: string): Promise<{ width: number; height: number }> => new Promise((resolve, reject) => { Image.getSize( uri, (width, height) => resolve({ width, height }), reject ); }); try { const { width, height } = await getImageSize(uri); let targetWidth = width; let targetHeight = height; if (width > maxSize || height > maxSize) { if (width > height) { targetWidth = maxSize; targetHeight = Math.round((height / width) * maxSize); } else { targetHeight = maxSize; targetWidth = Math.round((width / height) * maxSize); } } const manipResult = await ImageManipulator.manipulateAsync( uri, [ { resize: { width: targetWidth, height: targetHeight, }, }, ], { compress: 0.7, format: ImageManipulator.SaveFormat.WEBP, base64: false, } ); const response = await fetch(manipResult.uri); const blob = await response.blob(); const filename = uri.split('/').pop() || `image_${Date.now()}.webp`; const file = new File([blob], filename, { type: 'image/webp' }); return { uri: manipResult.uri, file }; } catch (error) { throw error; } };