feat: conversion HEIC serveur via sharp (fallback fiable Chrome/Firefox)
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { getServerSession } from 'next-auth'
|
||||
import { authOptions } from '@/lib/auth'
|
||||
import sharp from 'sharp'
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
const session = await getServerSession(authOptions)
|
||||
if (!session) return NextResponse.json({ error: 'Non authentifié' }, { status: 401 })
|
||||
|
||||
try {
|
||||
const formData = await req.formData()
|
||||
const file = formData.get('file') as File | null
|
||||
if (!file) return NextResponse.json({ error: 'Fichier manquant' }, { status: 400 })
|
||||
|
||||
const buffer = Buffer.from(await file.arrayBuffer())
|
||||
const jpegBuffer = await sharp(buffer).jpeg({ quality: 92 }).toBuffer()
|
||||
|
||||
return new NextResponse(jpegBuffer.buffer as ArrayBuffer, {
|
||||
headers: {
|
||||
'Content-Type': 'image/jpeg',
|
||||
'Content-Length': String(jpegBuffer.length),
|
||||
},
|
||||
})
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : 'Erreur conversion'
|
||||
return NextResponse.json({ error: message }, { status: 500 })
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,16 @@ export async function convertHeicToJpeg(blob: Blob): Promise<Blob> {
|
||||
console.warn(`[heicConverter] Conversion native échouée (${(e as Error).message}), repasse sur heic2any…`)
|
||||
}
|
||||
|
||||
// Méthode 2 : heic2any fallback (plus lent, ~10-30s)
|
||||
// Méthode 2 : conversion serveur via /api/images/convert-heic (sharp, fiable sur tous les navigateurs)
|
||||
try {
|
||||
const result = await convertViaServer(blob)
|
||||
console.log('[heicConverter] ✅ Conversion serveur réussie')
|
||||
return result
|
||||
} catch (e) {
|
||||
console.warn(`[heicConverter] Conversion serveur échouée (${(e as Error).message}), repasse sur heic2any…`)
|
||||
}
|
||||
|
||||
// Méthode 3 : heic2any fallback (plus lent, ~10-30s)
|
||||
const heic2any = (await import('heic2any')).default
|
||||
|
||||
const timeout = new Promise<never>((_, reject) =>
|
||||
@@ -81,6 +90,18 @@ async function convertNative(blob: Blob): Promise<Blob> {
|
||||
})
|
||||
}
|
||||
|
||||
async function convertViaServer(blob: Blob): Promise<Blob> {
|
||||
const formData = new FormData()
|
||||
const file = blob instanceof File ? blob : new File([blob], 'image.heic', { type: 'image/heic' })
|
||||
formData.append('file', file)
|
||||
const res = await fetch('/api/images/convert-heic', { method: 'POST', body: formData })
|
||||
if (!res.ok) {
|
||||
const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }))
|
||||
throw new Error(err.error ?? `HTTP ${res.status}`)
|
||||
}
|
||||
return res.blob()
|
||||
}
|
||||
|
||||
function canvasToBlob(canvas: HTMLCanvasElement): Promise<Blob> {
|
||||
return new Promise((resolve, reject) => {
|
||||
canvas.toBlob(
|
||||
|
||||
Reference in New Issue
Block a user