Windows MetaFile (WMF) Parser
The `wmf` package, currently at stable version 1.0.2, provides a pure JavaScript parser and renderer for Windows MetaFile (WMF) image files. It enables developers to extract image dimensions and draw WMF content onto HTML Canvas elements in both browser and Node.js environments. Unlike solutions that often require server-side processing or native libraries for WMF parsing, `wmf` offers a client-side or server-side (Node.js) JavaScript-only approach. Its primary purpose is to make a legacy image format accessible within modern web and Node.js applications. The library is specialized for this niche, implying a stable but infrequent release cadence focused on maintaining compatibility and reliability for WMF processing rather than rapid feature expansion. It ships with TypeScript types, facilitating type-safe development.
Common errors
-
ReferenceError: ImageData is not defined
cause The `wmf` library attempts to use the `ImageData` constructor, which is a browser-specific global API, in a Node.js environment without it being shimmed.fixIn your Node.js application, add `global.ImageData = require('canvas').createImageData;` (assuming you have `canvas` installed) before initializing or using the `wmf` library.
Warnings
- gotcha The `wmf` library depends on a global `ImageData` constructor. In Node.js environments, this browser API must be manually shimmed using a compatible implementation, such as `createImageData` from the `canvas` npm package.
- gotcha When using `OffscreenCanvas` with `wmf.draw_canvas`, some implementations (like Chrome's) require the canvas dimensions to be passed to its constructor. Failing to do so can result in an uninitialized or incorrectly sized canvas.
Install
-
npm install wmf -
yarn add wmf -
pnpm add wmf
Imports
- WMF
import { WMF } from 'wmf';import WMF from 'wmf';
- WMF (CommonJS)
import WMF from 'wmf';
const WMF = require('wmf'); - WMF (Browser Global)
import WMF from 'wmf'; // In browser HTML directly
<script src="wmf.js"></script> // WMF is now globally available
Quickstart
import { createCanvas, createImageData } from "canvas";
import WMF from "wmf";
import fs from "fs";
// Create a dummy WMF buffer for demonstration
// In a real application, replace this with actual WMF file data
// This is a minimal, non-functional WMF header placeholder.
// For actual use, ensure 'image.wmf' exists or generate a valid one.
const dummyWmfBuffer = Buffer.from([
0xD7, 0xCD, 0xC6, 0x9A, 0x00, 0x00, 0x00, 0x00, // Header magic
0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
]);
// Use a real WMF file path if available, otherwise use dummy for structure
const wmfFilePath = './test_image.wmf'; // Ensure this file exists for actual execution
let wmfData: Buffer;
try {
wmfData = fs.readFileSync(wmfFilePath);
console.log(`Using WMF file: ${wmfFilePath}`);
} catch (error) {
console.warn(`Could not read ${wmfFilePath}. Using dummy buffer. For actual rendering, provide a valid WMF file.`);
wmfData = dummyWmfBuffer;
}
// Shim ImageData for Node.js environments, required by wmf
global.ImageData = createImageData;
try {
// Extract image dimensions
const size = WMF.image_size(wmfData);
console.log(`Detected WMF size: ${size[0]}x${size[1]} pixels`);
// Create a canvas with the determined dimensions
const canvas = createCanvas(size[0], size[1]);
const ctx = canvas.getContext('2d');
// Draw the WMF content onto the canvas
WMF.draw_canvas(wmfData, canvas);
// Save the canvas content to a PNG file
const outputPngPath = './output.png';
const buffer = canvas.toBuffer('image/png');
fs.writeFileSync(outputPngPath, buffer);
console.log(`WMF content successfully rendered and saved to ${outputPngPath}`);
} catch (error) {
console.error("Error processing WMF:", error);
}