48 lines
1.9 KiB
TypeScript
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'}`);
|
|
}
|
|
};
|