Apple devices capture photos in the HEIC (High Efficiency Image Container) format by default to save storage space. However, when building web applications or processing user uploads, you often need these images in universally supported formats like JPEG.
In this guide, we will explore how HEIC works and how you can implement conversion logic using Node.js on the backend and JavaScript on the frontend.
- Why HEIC Conversion Matters for Developers While HEIC offers superior compression compared to JPEG, it presents compatibility challenges:
Browser Support: Most web browsers still do not natively render HEIC files directly in standard tags across all operating systems.
User Experience: Users expect to upload photos straight from their iPhones, but legacy systems often reject non-JPEG formats.
If you are looking for a quick, no-code solution for everyday tasks, you can always use a dedicated web tool like HEIC to JPG to instantly batch-convert your images. But if you are building an app, read on!
- Server-Side Conversion Using Node.js For backend environments, we can use the popular heic-convert package combined with sharp for image processing.
Step-by-Step Implementation
First, install the necessary dependencies via npm:
npm install heic-convert sharp
Next, write a conversion script:
const fs = require('fs');
const convert = require('heic-convert');
async function convertHeicToJpg(inputPath, outputPath) {
try {
const inputBuffer = fs.readFileSync(inputPath);
// Convert HEIC buffer to JPEG buffer
const outputBuffer = await convert({
buffer: inputBuffer,
format: 'JPEG',
quality: 0.85 // Adjust quality from 0 to 1
});
fs.writeFileSync(outputPath, outputBuffer);
console.log('Successfully converted HEIC to JPEG!');
} catch (error) {
console.error('Error during conversion:', error);
}
}
convertHeicToJpg('input.heic', 'output.jpg');
- Client-Side Processing with JavaScript If you want to handle conversions directly in the browser before uploading files to your server (saving bandwidth), you can leverage WebAssembly-based libraries or canvas APIs, though heavy decoding usually requires specialized libraries like heic2any.
import heic2any from "heic2any";
async function handleImageUpload(fileEvent) {
const file = fileEvent.target.files[0];
if (file.type === "image/heic" || file.name.endsWith(".heic")) {
try {
// Convert HEIC blob to JPEG blob
const convertedBlob = await heic2any({
blob: file,
toType: "image/jpeg",
quality: 0.9
});
// Create an object URL to preview or upload
const imageUrl = URL.createObjectURL(convertedBlob);
console.log("Converted image ready:", imageUrl);
} catch (error) {
console.error("Client-side conversion failed:", error);
}
}
}
Conclusion
Handling modern image formats like HEIC is a common hurdle in modern web development. Whether you choose a server-side pipeline with Node.js or client-side processing, handling this gracefully ensures a smooth user experience.
If you ever need a fast, browser-based bulk converter for your workflow without writing code, check out HEIC to JPG.
Top comments (1)
heic2any can return an array when the HEIC holds more than one image. URL.createObjectURL(convertedBlob) then gets an array, not a Blob. Check Array.isArray before creating the URL. On Chrome, file.type for these files is often empty, so the .heic suffix is what actually enters the branch, and .HEIC misses it.