Skip to content

Getting started ​

emf-converter converts Windows metafiles into PNG or SVG:

FormatDescriptionCoordinate system
WMFWindows Metafile (16-bit)Window/viewport mapping
EMFEnhanced Metafile (32-bit GDI)Bounds-based scaling
EMF+GDI+ extension embedded in EMFWorld transform matrix

Metafiles are recorded GDI and GDI+ drawing calls. They are common in Office documents and on the Windows clipboard. The library replays those calls in the same way Windows does. PNG output is compared pixel by pixel with images rendered by Windows (the fixtures are in src/__fixtures__/gdi, generated by scripts/gdi-fixtures). SVG output keeps paths, text and gradients as vectors.

Installation ​

sh
npm install emf-converter
sh
pnpm add emf-converter
sh
yarn add emf-converter
sh
bun add emf-converter

The package has no required dependencies.

Browser and Web Workers ​

OffscreenCanvas or HTMLCanvasElement is used automatically for PNG output.

Node.js ​

SVG output works without a canvas. PNG output of drawings without text uses the built-in JavaScript rasteriser.

For PNG output of drawings that contain text, do one of the following:

  • Pass font files with the fonts option. See Exact text.

  • Install the optional @napi-rs/canvas package. It ships prebuilt binaries and does not need node-gyp.

    sh
    npm install @napi-rs/canvas

If neither is available, PNG conversion of a drawing with text returns null instead of an image without its text.

First conversion ​

ts
import { convertMetafileToDataUrl } from 'emf-converter';

const buffer: ArrayBuffer = /* contents of an .emf or .wmf file */;
const png = await convertMetafileToDataUrl(buffer);
// "data:image/png;base64,iVBORw0KGgo..."

The function returns Promise<string | null>. The result is null when the buffer is not a valid metafile, or, in plain Node.js, when the drawing has text and neither fonts nor @napi-rs/canvas is available.

Reading a file in Node.js:

ts
import { readFile } from 'node:fs/promises';
import { convertMetafileToSvg } from 'emf-converter';

const bytes = await readFile('drawing.emf');
const buffer = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
const svg = await convertMetafileToSvg(buffer);

Next: Usage.

Released under the Apache-2.0 License.