2025-07-17 15:44:34 +08:00

48 lines
1.9 KiB
TypeScript

import * as FileSystem from 'expo-file-system';
// 将 HEIC/HEIF 图片转为 JPEG
export const convertHeicToJpeg = async (uri: string): Promise<File> => {
try {
// 1. 将文件复制到缓存目录
const cacheDir = FileSystem.cacheDirectory;
if (!cacheDir) {
throw new Error('Cache directory not available');
}
const tempUri = `${cacheDir}${Date.now()}.heic`;
await FileSystem.copyAsync({ from: uri, to: tempUri });
// 2. 检查文件是否存在
const fileInfo = await FileSystem.getInfoAsync(tempUri);
if (!fileInfo.exists) {
throw new Error('Temporary file was not created');
}
// 3. 读取文件为 base64
const base64 = await FileSystem.readAsStringAsync(tempUri, {
encoding: FileSystem.EncodingType.Base64,
});
if (!base64) {
throw new Error('Failed to read file as base64');
}
// 4. 创建 Blob
const response = await fetch(`data:image/jpeg;base64,${base64}`);
if (!response.ok) {
throw new Error(`Fetch failed with status ${response.status}`);
}
const blob = await response.blob();
if (!blob || blob.size === 0) {
throw new Error('Failed to create blob from base64');
}
// 5. 创建文件名
const originalName = uri.split('/').pop() || 'converted';
const filename = originalName.replace(/\.(heic|heif)$/i, '.jpg');
// 清理临时文件
try {
await FileSystem.deleteAsync(tempUri, { idempotent: true });
} catch (cleanupError) {
console.warn('Failed to clean up temporary file:', cleanupError);
}
return new File([blob], filename, { type: 'image/jpeg' });
} catch (error: unknown) {
throw new Error(`Failed to convert HEIC image: ${error instanceof Error ? error.message : 'An unknown error occurred'}`);
}
};