fix: conversion HEIC serveur via heic-convert (WASM, supporte HEIC Apple vs sharp AVIF only)

This commit is contained in:
2026-06-09 11:50:00 +02:00
parent c4edcb568c
commit 2efe339576
4 changed files with 65 additions and 5 deletions
+51
View File
@@ -13,6 +13,7 @@
"bcryptjs": "^3.0.3",
"better-sqlite3": "^12.10.0",
"googleapis": "^173.0.0",
"heic-convert": "^2.1.0",
"heic2any": "^0.0.4",
"jszip": "^3.10.1",
"next": "14.2.35",
@@ -7342,6 +7343,32 @@
"node": ">= 0.4"
}
},
"node_modules/heic-convert": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/heic-convert/-/heic-convert-2.1.0.tgz",
"integrity": "sha512-1qDuRvEHifTVAj3pFIgkqGgJIr0M3X7cxEPjEp0oG4mo8GFjq99DpCo8Eg3kg17Cy0MTjxpFdoBHOatj7ZVKtg==",
"license": "ISC",
"dependencies": {
"heic-decode": "^2.0.0",
"jpeg-js": "^0.4.4",
"pngjs": "^6.0.0"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/heic-decode": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/heic-decode/-/heic-decode-2.1.0.tgz",
"integrity": "sha512-0fB3O3WMk38+PScbHLVp66jcNhsZ/ErtQ6u2lMYu/YxXgbBtl+oKOhGQHa4RpvE68k8IzbWkABzHnyAIjR758A==",
"license": "ISC",
"dependencies": {
"libheif-js": "^1.19.8"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/heic2any": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/heic2any/-/heic2any-0.0.4.tgz",
@@ -9165,6 +9192,12 @@
"url": "https://github.com/sponsors/panva"
}
},
"node_modules/jpeg-js": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.4.tgz",
"integrity": "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==",
"license": "BSD-3-Clause"
},
"node_modules/js-tokens": {
"version": "4.0.0",
"license": "MIT"
@@ -9414,6 +9447,15 @@
"node": ">= 0.8.0"
}
},
"node_modules/libheif-js": {
"version": "1.19.8",
"resolved": "https://registry.npmjs.org/libheif-js/-/libheif-js-1.19.8.tgz",
"integrity": "sha512-vQJWusIxO7wavpON1dusciL8Go9jsIQ+EUrckauFYAiSTjcmLAsuJh3SszLpvkwPci3JcL41ek2n+LUZGFpPIQ==",
"license": "LGPL-3.0",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/lie": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
@@ -10594,6 +10636,15 @@
"pathe": "^2.0.3"
}
},
"node_modules/pngjs": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz",
"integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==",
"license": "MIT",
"engines": {
"node": ">=12.13.0"
}
},
"node_modules/possible-typed-array-names": {
"version": "1.1.0",
"dev": true,
+1
View File
@@ -18,6 +18,7 @@
"bcryptjs": "^3.0.3",
"better-sqlite3": "^12.10.0",
"googleapis": "^173.0.0",
"heic-convert": "^2.1.0",
"heic2any": "^0.0.4",
"jszip": "^3.10.1",
"next": "14.2.35",
+12 -5
View File
@@ -1,7 +1,7 @@
import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import sharp from 'sharp'
import convert from 'heic-convert'
export async function POST(req: NextRequest) {
const session = await getServerSession(authOptions)
@@ -12,17 +12,24 @@ export async function POST(req: NextRequest) {
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()
const inputBuffer = Buffer.from(await file.arrayBuffer())
// heic-convert utilise libheif WASM — supporte HEIC/HEIF sur tous les environnements
const outputBuffer = await convert({
buffer: inputBuffer,
format: 'JPEG',
quality: 0.92,
})
return new NextResponse(jpegBuffer.buffer as ArrayBuffer, {
const jpeg = Buffer.from(outputBuffer)
return new NextResponse(jpeg.buffer as ArrayBuffer, {
headers: {
'Content-Type': 'image/jpeg',
'Content-Length': String(jpegBuffer.length),
'Content-Length': String(jpeg.length),
},
})
} catch (err) {
const message = err instanceof Error ? err.message : 'Erreur conversion'
console.error('[convert-heic API]', message)
return NextResponse.json({ error: message }, { status: 500 })
}
}
+1
View File
@@ -0,0 +1 @@
declare module 'heic-convert';