| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- const HEIC_MIME_TYPES = [
- 'image/heic',
- 'image/heif',
- 'image/heic-sequence',
- 'image/heif-sequence',
- ]
- export function isHeicOrHeif(file: File): boolean {
- const name = file.name.toLowerCase()
- const type = (file.type || '').toLowerCase()
- return (
- name.endsWith('.heic') ||
- name.endsWith('.heif') ||
- HEIC_MIME_TYPES.includes(type)
- )
- }
- function replaceExtension(fileName: string, extension: string): string {
- const lastDot = fileName.lastIndexOf('.')
- if (lastDot <= 0) return `${fileName}.${extension}`
- return `${fileName.slice(0, lastDot)}.${extension}`
- }
- export async function convertHeicHeifToWebp(file: File): Promise<File> {
- const type = (file.type || '').toLowerCase()
- // If the blob already has a browser-readable image MIME (and it's not a HEIC MIME),
- // skip conversion and return the original file.
- if (type && type.startsWith('image/') && !HEIC_MIME_TYPES.includes(type)) {
- return file
- }
- const { default: heic2any } = await import('heic2any')
- try {
- const result = await heic2any({
- blob: file,
- toType: 'image/webp',
- quality: 0.92,
- })
- const blob = Array.isArray(result) ? result[0] : result
- if (!(blob instanceof Blob)) {
- throw new Error('HEIC/HEIF 转换失败')
- }
- const targetFileName = replaceExtension(file.name, 'webp')
- return new File([blob], targetFileName, {
- type: 'image/webp',
- lastModified: Date.now(),
- })
- } catch (err: any) {
- // heic2any may throw when the provided blob is already browser-readable
- // (e.g. it contains image/jpeg despite .heic extension). In that case,
- // treat it as already-converted and return the original file.
- const msg = String(err?.message || '')
- if (err && (err.code === 1 || /already browser readable/i.test(msg))) {
- return file
- }
- throw err instanceof Error ? err : new Error('HEIC/HEIF 转换失败')
- }
- }
|