Skip to content

catdad-experiments/libheif-js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

libheif-js

An Emscripten build of libheif distributed as an npm module for Node.JS and the browser.

github actions test jsdelivr npm-downloads npm-version

This module will respect the major and minor versions of the included libheif, with the patch version representing changes in this module itself. For the exact version of libheif, please see the install script.

Install

npm install libheif-js

Usage

Starting with version 1.17, there are multiple variants of libheif that you can use:

  • The default is still the classic pure-javascript implementation (for backwards compatibility, of course). You can still bundle this into your project with your bundler of choice.
    const libheif = require('libheif-js');
  • There is a wasm version available for use in NodeJS. This version will dymanically load the .wasm binary at runtime. While you may try to run this through a bundler, you are on your own for making it work.
    const libheif = require('libheif-js/wasm');
  • There is also a wasm version that is pre-bundled for you, which includes the .wasm binary inside the .js bundle. You will have a much easier time using this in your browser bundle project.
    const libheif = require('libheif-js/wasm-bundle');

If you'd like to include this module directly into an html page using a <script> tag, you have the following options:

Note: in the examples below, make sure to set the latest version when you use it. Always make sure to set a version, to make sure your website does not break unexpectedly when an update is released.

  • Use the pure-javascript implementation, exposing a libheif global:
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/libheif/libheif.js"></script>
  • Use the wasm bundle, exposing a libheif global:
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/libheif-wasm/libheif-bundle.js"></script>
  • Use the ES Module version, which now works in all major browsers and you should try it:
    <script type="module">
      import libheif from 'https://cdn.jsdelivr.net/npm/[email protected]/libheif-wasm/libheif-bundle.mjs';
    </script>

In all cases, you can use this sample code to decode an image:

const file = fs.readFileSync('./temp/0002.heic');

const decoder = new libheif.HeifDecoder();
const data = decoder.decode(file);
// data in an array holding all images inside the heic file

const image = data[0];
const width = image.get_width();
const height = image.get_height();

In NodeJS, you might use this decoded data with other libraries, such as pngjs:

const { PNG } = require('pngjs');

const imageData = await new Promise((resolve, reject) => {
  image.display({ data: new Uint8ClampedArray(width*height*4), width, height }, (displayData) => {
    if (!displayData) {
      return reject(new Error('HEIF processing error'));
    }

    resolve(displayData);
  });
});

const png = new PNG({ width: imageData.width, height: imageData.height });
png.data = imageData.data;

const pngBuffer = PNG.sync.write(png);

In the browser, you might use this decoded data with canvas to display or convert the image:

const canvas = document.createElement('canvas');

canvas.width = width;
canvas.height = height;

const context = canvas.getContext('2d');
const imageData = context.createImageData(width, height);

await new Promise((resolve, reject) => {
  image.display(imageData, (displayData) => {
    if (!displayData) {
      return reject(new Error('HEIF processing error'));
    }

    resolve();
  });
});

context.putImageData(imageData, 0, 0);

Related

This module contains the low-level libheif implementation. For more user-friendly functionality, check out these projects:

  • heic-cli - convert heic/heif images to jpeg or png from the command line
  • heic-convert - convert heic/heif images to jpeg and png
  • heic-decode - decode heic images to raw image data