WMF Windows metafile

AI-powered detection and analysis of Windows metafile files.

📂 Image
🏷️ .wmf
🎯 image/wmf
🔍

Instant WMF File Detection

Use our advanced AI-powered tool to instantly detect and analyze Windows metafile files with precision and speed.

File Information

File Description

Windows metafile

Category

Image

Extensions

.wmf

MIME Type

image/wmf

WMF (Windows Metafile) Format

Overview

Windows Metafile (WMF) is a graphics file format developed by Microsoft for storing vector and bitmap graphics. WMF files contain drawing commands that can be replayed to recreate images, making them resolution-independent and scalable.

Technical Specifications

  • Format Type: Vector graphics metafile
  • File Extension: .wmf
  • MIME Type: image/wmf
  • Bit Depth: Supports various color depths
  • Compression: None (stores drawing commands)
  • Maximum Size: 64KB due to 16-bit addressing
  • Coordinate System: Device-dependent or device-independent

Format Structure

WMF files consist of:

  • Header with metadata and file information
  • Series of metafile records (drawing commands)
  • Placeable WMF header (optional, for positioning)
  • Graphics Device Interface (GDI) function calls
  • End-of-file record

History and Development

  • 1988: Introduction with Windows 2.0
  • 1990: Enhanced in Windows 3.0
  • 1995: Succeeded by Enhanced Metafile (EMF) format
  • 1998: Security concerns led to restricted usage
  • 2000s: Largely replaced by newer formats but still supported

WMF Record Types

  • Drawing commands: Lines, curves, shapes, text
  • Attribute changes: Colors, fonts, line styles
  • State management: Save/restore graphics state
  • Bitmap operations: Raster image embedding
  • Clipping: Define drawing boundaries

Use Cases

  • Legacy document formats
  • Vector graphics exchange
  • Clipboard operations in Windows
  • Scientific and technical drawings
  • CAD file interchange
  • Print spooling operations

Code Examples

C# WMF Reading and Processing

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

class WmfProcessor
{
    public static void ConvertWmfToPng(string wmfPath, string pngPath)
    {
        using (var metafile = new Metafile(wmfPath))
        {
            // Get metafile bounds
            var bounds = metafile.GetBounds(ref GraphicsUnit.Pixel);
            
            // Create bitmap to render metafile
            using (var bitmap = new Bitmap((int)bounds.Width, (int)bounds.Height))
            {
                using (var graphics = Graphics.FromImage(bitmap))
                {
                    graphics.Clear(Color.White);
                    graphics.DrawImage(metafile, Point.Empty);
                }
                
                bitmap.Save(pngPath, ImageFormat.Png);
            }
        }
    }
    
    public static void CreateWmfFromDrawing(string outputPath)
    {
        using (var bitmap = new Bitmap(400, 300))
        {
            using (var graphics = Graphics.FromImage(bitmap))
            {
                // Create metafile from graphics context
                IntPtr hdc = graphics.GetHdc();
                
                var bounds = new Rectangle(0, 0, 400, 300);
                using (var metafile = new Metafile(outputPath, hdc, bounds, MetafileFrameUnit.Pixel))
                {
                    using (var metaGraphics = Graphics.FromImage(metafile))
                    {
                        // Draw shapes that will be recorded as WMF commands
                        metaGraphics.DrawRectangle(Pens.Black, 10, 10, 100, 80);
                        metaGraphics.FillEllipse(Brushes.Red, 150, 20, 60, 60);
                        metaGraphics.DrawString("Hello WMF", 
                            new Font("Arial", 16), Brushes.Blue, 50, 150);
                    }
                }
                
                graphics.ReleaseHdc(hdc);
            }
        }
    }
    
    public static void AnalyzeWmfMetadata(string wmfPath)
    {
        using (var metafile = new Metafile(wmfPath))
        {
            var header = metafile.GetMetafileHeader();
            
            Console.WriteLine($"Type: {header.Type}");
            Console.WriteLine($"Size: {header.Size} bytes");
            Console.WriteLine($"Version: {header.Version:X}");
            Console.WriteLine($"DPI X: {header.DpiX}");
            Console.WriteLine($"DPI Y: {header.DpiY}");
            Console.WriteLine($"Bounds: {header.Bounds}");
            Console.WriteLine($"Empty: {header.IsEmpty()}");
            Console.WriteLine($"Display: {header.IsDisplay()}");
        }
    }
}

Python WMF Processing with Pillow

from PIL import Image, ImageDraw, ImageFont
import struct

class WmfProcessor:
    def __init__(self):
        self.records = []
    
    def read_wmf_header(self, filename):
        """Read WMF file header information."""
        with open(filename, 'rb') as f:
            # Check for Placeable WMF header
            magic = struct.unpack('<I', f.read(4))[0]
            
            if magic == 0x9AC6CDD7:  # Placeable WMF
                # Read placeable header
                hmf = struct.unpack('<H', f.read(2))[0]
                left, top, right, bottom = struct.unpack('<4h', f.read(8))
                inch = struct.unpack('<H', f.read(2))[0]
                reserved = struct.unpack('<I', f.read(4))[0]
                checksum = struct.unpack('<H', f.read(2))[0]
                
                return {
                    'type': 'Placeable WMF',
                    'bounds': (left, top, right, bottom),
                    'dpi': inch,
                    'checksum': checksum
                }
            else:
                # Standard WMF header
                f.seek(0)
                file_type = struct.unpack('<H', f.read(2))[0]
                header_size = struct.unpack('<H', f.read(2))[0]
                version = struct.unpack('<H', f.read(2))[0]
                file_size = struct.unpack('<I', f.read(4))[0]
                
                return {
                    'type': 'Standard WMF',
                    'header_size': header_size,
                    'version': f'0x{version:04X}',
                    'file_size': file_size
                }
    
    def convert_wmf_to_image(self, wmf_path, output_path, size=(400, 300)):
        """Convert WMF to raster image using approximation."""
        try:
            # Try to open with Pillow (limited WMF support)
            with Image.open(wmf_path) as img:
                img = img.resize(size, Image.Resampling.LANCZOS)
                img.save(output_path)
                return True
        except Exception as e:
            print(f"Error converting WMF: {e}")
            return False
    
    def create_sample_wmf_like(self, output_path, size=(400, 300)):
        """Create a sample image that mimics WMF content."""
        img = Image.new('RGB', size, 'white')
        draw = ImageDraw.Draw(img)
        
        # Draw various shapes (simulating WMF commands)
        draw.rectangle([10, 10, 110, 90], outline='black', width=2)
        draw.ellipse([150, 20, 210, 80], fill='red')
        draw.line([250, 30, 350, 70], fill='blue', width=3)
        draw.polygon([(50, 150), (100, 120), (150, 150), (125, 200)], 
                    fill='green', outline='darkgreen')
        
        # Add text
        try:
            font = ImageFont.truetype("arial.ttf", 16)
        except:
            font = ImageFont.load_default()
        
        draw.text((50, 220), "WMF Sample", fill='black', font=font)
        
        img.save(output_path)

# Usage example
processor = WmfProcessor()
header_info = processor.read_wmf_header('sample.wmf')
print("WMF Header:", header_info)

processor.convert_wmf_to_image('input.wmf', 'output.png')
processor.create_sample_wmf_like('sample.png')

JavaScript WMF Header Parser

class WmfParser {
    constructor(buffer) {
        this.buffer = buffer;
        this.view = new DataView(buffer);
        this.offset = 0;
    }
    
    readUint16() {
        const value = this.view.getUint16(this.offset, true); // little endian
        this.offset += 2;
        return value;
    }
    
    readUint32() {
        const value = this.view.getUint32(this.offset, true);
        this.offset += 4;
        return value;
    }
    
    readInt16() {
        const value = this.view.getInt16(this.offset, true);
        this.offset += 2;
        return value;
    }
    
    parseHeader() {
        this.offset = 0;
        
        // Check for Placeable WMF magic number
        const magic = this.readUint32();
        
        if (magic === 0x9AC6CDD7) {
            return this.parsePlaceableHeader();
        } else {
            this.offset = 0;
            return this.parseStandardHeader();
        }
    }
    
    parsePlaceableHeader() {
        const hmf = this.readUint16();
        const left = this.readInt16();
        const top = this.readInt16();
        const right = this.readInt16();
        const bottom = this.readInt16();
        const inch = this.readUint16();
        const reserved = this.readUint32();
        const checksum = this.readUint16();
        
        return {
            type: 'Placeable WMF',
            handle: hmf,
            bounds: { left, top, right, bottom },
            unitsPerInch: inch,
            checksum: checksum,
            width: right - left,
            height: bottom - top
        };
    }
    
    parseStandardHeader() {
        const fileType = this.readUint16();
        const headerSize = this.readUint16();
        const version = this.readUint16();
        const fileSize = this.readUint32();
        const numObjects = this.readUint16();
        const maxRecord = this.readUint32();
        const numMembers = this.readUint16();
        
        return {
            type: 'Standard WMF',
            fileType: fileType,
            headerSize: headerSize,
            version: `0x${version.toString(16).toUpperCase()}`,
            fileSize: fileSize,
            numObjects: numObjects,
            maxRecordSize: maxRecord,
            numMembers: numMembers
        };
    }
}

// Usage example
async function analyzeWmfFile(file) {
    const buffer = await file.arrayBuffer();
    const parser = new WmfParser(buffer);
    const header = parser.parseHeader();
    
    console.log('WMF Header Information:');
    console.table(header);
    
    return header;
}

// HTML file input handler
document.getElementById('wmfInput').addEventListener('change', (event) => {
    const file = event.target.files[0];
    if (file && file.name.toLowerCase().endsWith('.wmf')) {
        analyzeWmfFile(file);
    }
});

Security Considerations

  • Historical vulnerabilities: WMF format has had security issues
  • Parsing risks: Malformed files can cause crashes or exploits
  • Limited support: Many modern applications don't support WMF
  • Code execution: WMF files can contain executable code
  • Validation required: Always validate WMF files from untrusted sources

Conversion and Migration

Converting WMF to Modern Formats

# Using ImageMagick (if WMF support is available)
convert input.wmf output.svg
convert input.wmf output.png

# Using Inkscape
inkscape --file=input.wmf --export-plain-svg=output.svg
inkscape --file=input.wmf --export-png=output.png --export-dpi=300

# Using LibreOffice command line
libreoffice --headless --convert-to svg input.wmf
libreoffice --headless --convert-to pdf input.wmf

Batch Conversion Script

# PowerShell script for batch WMF conversion
$wmfFiles = Get-ChildItem -Path "C:\WMF_Files" -Filter "*.wmf"

foreach ($file in $wmfFiles) {
    $outputPath = $file.FullName -replace '\.wmf$', '.png'
    
    try {
        # Using .NET System.Drawing
        $metafile = [System.Drawing.Imaging.Metafile]::FromFile($file.FullName)
        $bitmap = New-Object System.Drawing.Bitmap(800, 600)
        $graphics = [System.Drawing.Graphics]::FromImage($bitmap)
        $graphics.DrawImage($metafile, [System.Drawing.Point]::Empty)
        $bitmap.Save($outputPath, [System.Drawing.Imaging.ImageFormat]::Png)
        
        $graphics.Dispose()
        $bitmap.Dispose()
        $metafile.Dispose()
        
        Write-Host "Converted: $($file.Name) -> $([System.IO.Path]::GetFileName($outputPath))"
    }
    catch {
        Write-Error "Failed to convert $($file.Name): $($_.Exception.Message)"
    }
}

Best Practices

  • Avoid using WMF for new projects
  • Convert legacy WMF files to modern formats (SVG, PNG, PDF)
  • Implement proper security validation for WMF files
  • Use EMF format instead of WMF when possible
  • Test WMF rendering across different applications
  • Maintain backup copies during format migration

Modern Alternatives

  • SVG: Scalable Vector Graphics (web standard)
  • EMF: Enhanced Metafile (improved WMF successor)
  • PDF: Portable Document Format
  • EPS: Encapsulated PostScript
  • PNG/JPEG: For raster conversion
  • WebP: Modern image format with vector support

Troubleshooting Common Issues

  • Rendering problems: Use compatible viewers or converters
  • Size limitations: WMF limited to 64KB, use EMF for larger files
  • Color issues: Check color palette and bit depth settings
  • Font problems: Ensure fonts are available on target system
  • Scaling artifacts: Convert to vector formats for better scaling

AI-Powered WMF File Analysis

🔍

Instant Detection

Quickly identify Windows metafile files with high accuracy using Google's advanced Magika AI technology.

🛡️

Security Analysis

Analyze file structure and metadata to ensure the file is legitimate and safe to use.

📊

Detailed Information

Get comprehensive details about file type, MIME type, and other technical specifications.

🔒

Privacy First

All analysis happens in your browser - no files are uploaded to our servers.

Related File Types

Explore other file types in the Image category and discover more formats:

Start Analyzing WMF Files Now

Use our free AI-powered tool to detect and analyze Windows metafile files instantly with Google's Magika technology.

Try File Detection Tool