Skip to content

reyco2000/Vintage-Vector-Image-Viewer

Repository files navigation

Vintage Vector Image Viewer

A Python-based GUI application for viewing and converting vintage vector graphics files with graphical rendering support. Supports both CGM (Computer Graphics Metafile) and WMF (Windows Metafile) formats. Includes an interactive Tkinter-based GUI viewer and command-line conversion tools.

Features:

  • CGM support with HiJaak 2 MIL-D-28003 extensions
  • WMF support for Windows 3.x metafiles
  • Interactive GUI with arrow key navigation
  • PNG export for both formats
  • SVG export for CGM files

Project Components

Main Applications

  • vvi_viewer.py - Interactive GUI viewer with Tkinter

    • Real-time rendering of CGM and WMF files using PIL/Pillow
    • Arrow key navigation through directories
    • PNG export for both CGM and WMF
    • SVG export for CGM files
    • Binary parsers for CGM (with HiJaak extensions) and WMF
  • cgm_to_svg.py - Command-line CGM to SVG converter

    • Batch conversion support
    • Configurable output dimensions
    • Uses cgm_svg_renderer.py for vector output

Supporting Modules

  • cgm_svg_renderer.py - SVG rendering engine

    • Converts CGM primitives to SVG elements
    • Handles coordinate transformation
    • Color table management
  • wmf_parser.py - WMF parser and renderer

    • Binary WMF parser for Windows Metafile format
    • PIL-based rendering engine
    • Supports placeable and standard WMF headers
    • GDI object management

Documentation & Testing

  • cgm_fileformat.md - Detailed CGM format specification
  • wmf_fileformat.md - Detailed WMF format specification
  • test_features.sh - Automated testing script
  • Sample_Files/ - Sample vector graphics (OWL1.CGM, BUTRFLY.WMF, sample.wmf)
  • CLAUDE.md - Development notes and architecture guide
  • FEATURES.md - Feature list and implementation status

Features

  • Multi-Format Support: Renders both CGM and WMF vector graphics

  • CGM Support:

    • Polylines and polygons
    • Rectangles and circles
    • Text elements
    • Color and line width attributes
    • HiJaak vendor extensions (Element 23)
    • Binary encoding (ISO/IEC 8632)
  • WMF Support:

    • Polylines and polygons
    • Rectangles and ellipses
    • Lines (LINETO/MOVETO)
    • Text elements
    • GDI objects (pens, brushes)
    • Placeable metafile headers
    • Windows 3.x era metafiles
  • Arrow Key Navigation: Browse through vector files in a directory

    • ← Previous file
    • → Next file
    • File counter shows position (e.g., "file.wmf (2/5)")
    • Works with mixed CGM/WMF directories
  • Export Options:

    • Save as PNG - High-quality bitmap export (CGM and WMF)
    • Save as SVG - Scalable vector graphics (CGM only)
  • Browse Function: Easy file selection with dialog supporting both formats

Requirements

System Requirements

  • Python 3.6+ (Python 3.7+ recommended)
  • tkinter - GUI framework (uses TCL/Tk)
    • Usually included with Python standard installations
    • Required by vvi_viewer.py
  • Pillow - Python Imaging Library for raster graphics
    • Required by vvi_viewer.py

Dependencies

Install Python dependencies:

pip install -r requirements.txt

Or manually:

pip install pillow

Installing tkinter (if not included)

Most Python installations include tkinter by default. If you encounter ModuleNotFoundError: No module named 'tkinter':

Ubuntu/Debian:

sudo apt-get install python3-tk

Fedora/RHEL:

sudo dnf install python3-tkinter

macOS:

  • Usually included with Python from python.org
  • Homebrew: brew install python-tk

Windows:

  • Reinstall Python from python.org with "tcl/tk and IDLE" option checked

Installation

  1. Clone or download this repository

  2. Ensure Python 3.6+ is installed:

    python --version
  3. Install dependencies:

    pip install -r requirements.txt
  4. Verify tkinter is available:

    python -c "import tkinter; print('tkinter OK')"

Usage

GUI Viewer (vvi_viewer.py)

Launch the interactive viewer:

python vvi_viewer.py

Controls:

  1. Click "Browse Vector File" to select a file (.cgm or .wmf)
  2. View rendered graphics in the main window
  3. Use arrow keys for navigation:
    • Previous file in directory
    • Next file in directory
    • Works with mixed CGM/WMF directories
  4. Export options:
    • "Save as PNG" - Raster image export (both CGM and WMF)
    • "Save as SVG" - Vector graphics export (CGM only)

GUI Features:

  • Automatic format detection (CGM or WMF)
  • File counter shows position (e.g., "OWL1.CGM (2/5)")
  • Status bar shows file format and rendering progress
  • Scrollable canvas for large graphics
  • Automatic directory file list management

Command-Line Tools

Basic SVG Conversion (cgm_to_svg.py)

Convert a single file to SVG:

python cgm_to_svg.py input.cgm output.svg

Convert with custom dimensions (width x height in pixels):

python cgm_to_svg.py input.cgm output.svg 1200 900

Parameters:

  • input.cgm - Source CGM file path
  • output.svg - Destination SVG file path
  • width (optional) - SVG width in pixels (default: 800)
  • height (optional) - SVG height in pixels (default: 600)

Batch Conversion

Bash/Linux/macOS:

# Convert all .cgm files in current directory
for f in *.cgm; do
  python cgm_to_svg.py "$f" "${f%.cgm}.svg"
done

# Convert all .CGM files (uppercase extension)
for f in *.CGM; do
  python cgm_to_svg.py "$f" "${f%.CGM}.svg"
done

Windows PowerShell:

Get-ChildItem *.cgm | ForEach-Object {
  python cgm_to_svg.py $_.Name ($_.BaseName + ".svg")
}

Windows Command Prompt:

for %f in (*.cgm) do python cgm_to_svg.py "%f" "%~nf.svg"

Supported Elements

CGM Elements

Delimiter Elements (Class 0):

  • BEGIN METAFILE, END METAFILE, BEGIN PICTURE, BEGIN PICTURE BODY, END PICTURE

Metafile Descriptor Elements (Class 1):

  • METAFILE VERSION, METAFILE DESCRIPTION, VDC TYPE, INTEGER PRECISION, COLOUR PRECISION

Picture Descriptor Elements (Class 2):

  • VDC EXTENT, BACKGROUND COLOUR, COLOUR SELECTION MODE (Indexed/Direct RGB)

Graphical Primitive Elements (Class 4):

  • POLYLINE, POLYGON, TEXT, RECTANGLE, CIRCLE, CIRCULAR ARC (partial), ELLIPSE (simplified)

Attribute Elements (Class 5):

  • LINE WIDTH, LINE COLOUR (8-bit and 16-bit), FILL COLOUR (8-bit and 16-bit)
  • EDGE WIDTH, EDGE COLOUR, EDGE VISIBILITY, INTERIOR STYLE
  • Element 23 (HiJaak Fill Color Extension)

WMF Records

Drawing Records:

  • META_MOVETO, META_LINETO - Line drawing
  • META_POLYLINE, META_POLYGON - Multi-point shapes
  • META_RECTANGLE, META_ROUNDRECT, META_ELLIPSE - Basic shapes
  • META_TEXTOUT - Text rendering (basic)

Attribute Records:

  • META_SETBKCOLOR - Background color
  • META_SETWINDOWORG, META_SETWINDOWEXT - Window transformation
  • META_SETVIEWPORTORG, META_SETVIEWPORTEXT - Viewport transformation
  • META_SETMAPMODE - Coordinate mapping mode

Object Management:

  • META_CREATEPENINDIRECT - Create pen objects
  • META_CREATEBRUSHINDIRECT - Create brush objects
  • META_SELECTOBJECT - Select GDI object
  • META_DELETEOBJECT - Delete GDI object

HiJaak 2 Support

This viewer includes special support for HiJaak 2 MIL-D-28003/BASIC-1 CGM files, which use vendor-specific extensions:

  • Element 23 - Per-primitive fill color (not in ISO/IEC 8632 standard)
  • Proper handling of "Hollow" interior style
  • 16-bit RGB color values (converted to 8-bit internally)
  • Direct RGB color mode (color_mode=1)

Files from HiJaak software (military/technical documentation) will now render correctly!

Implementation: Both vvi_viewer.py (lines 651-664) and cgm_to_svg.py (lines 149-156) handle Element 23 by treating it as a fill color attribute, which is non-standard but necessary for HiJaak files.

Tested Formats

CGM: ✅ Standard ISO/IEC 8632 CGM files ✅ HiJaak 2 MIL-D-28003/BASIC-1 format ✅ Binary encoding ✅ Direct RGB and Indexed color modes ✅ 8-bit and 16-bit color precision

WMF: ✅ Standard Windows Metafile format ✅ Placeable metafiles (APM header) ✅ Windows 3.x era metafiles ✅ GDI-based graphics primitives

Limitations

  • This is a viewer for educational purposes
  • Not all CGM elements are fully supported
  • Complex CGM files may not render perfectly
  • Text rendering uses default fonts
  • Some advanced features (patterns, hatching, etc.) are not implemented
  • Clear text CGM format not yet supported

File Formats

CGM (Computer Graphics Metafile)

CGM is an ISO standard (ISO/IEC 8632) for 2D vector graphics. This viewer supports binary-encoded CGM files including vendor extensions.

For detailed format information, see cgm_fileformat.md in this repository.

WMF (Windows Metafile)

WMF is Microsoft's 16-bit graphics metafile format from the Windows 3.x era. It stores a sequence of GDI (Graphics Device Interface) function calls for vector graphics.

For detailed format information, see wmf_fileformat.md in this repository.

Architecture

Module Dependencies

vvi_viewer.py (GUI Application)
├── tkinter (GUI framework - uses TCL/Tk)
├── PIL/Pillow (image rendering)
├── struct (binary parsing)
├── wmf_parser.py (WMF parsing and rendering)
└── cgm_to_svg.py (CGM SVG export)
    └── cgm_svg_renderer.py (SVG generation)

Rendering Pipeline

GUI Viewer (vvi_viewer.py):

  1. File Loading: User selects CGM file via tkinter dialog
  2. Binary Parsing: Reads CGM command headers (element class, ID, parameters)
  3. Coordinate Transformation: Converts VDC (Virtual Device Coordinates) to screen pixels
  4. Raster Rendering: Uses PIL/Pillow ImageDraw to render primitives
  5. Display: Shows rendered image on tkinter Canvas
  6. Export: Can save as PNG (direct) or SVG (via cgm_to_svg.py)

SVG Converter (cgm_to_svg.py):

  1. Binary Parsing: Reads CGM command headers (same logic as GUI)
  2. Vector Rendering: Calls CGMSVGRenderer methods to build SVG elements
  3. SVG Generation: Outputs XML-based SVG file

Key Classes

CGMRenderer (in vvi_viewer.py, lines 15-234)

  • PIL-based raster renderer
  • Maintains graphics state (colors, line widths, styles)
  • Methods: draw_polyline(), draw_polygon(), draw_rectangle(), draw_circle(), draw_text()
  • Returns: PIL Image object

CGMViewer (in vvi_viewer.py, lines 237-780)

  • Tkinter GUI application
  • CGM binary parser
  • File navigation management
  • Export functionality

CGMSVGRenderer (in cgm_svg_renderer.py)

  • Pure Python SVG generator (no external dependencies)
  • Same API as CGMRenderer but outputs SVG elements
  • Returns: SVG XML string

File Reference

Vintage-VectorImage-Viewer/
├── vvi_viewer.py             # Main GUI application (multi-format viewer)
├── wmf_parser.py             # WMF parser and renderer
├── cgm_to_svg.py             # Command-line CGM to SVG converter
├── cgm_svg_renderer.py       # SVG rendering engine
├── requirements.txt          # Python dependencies
├── LICENSE                   # MIT License
├── README.md                 # This file
├── CLAUDE.md                 # Development guide and architecture notes
├── FEATURES.md               # Feature list and implementation status
├── cgm_fileformat.md         # Detailed CGM format specification
├── wmf_fileformat.md         # Detailed WMF format specification
├── test_features.sh          # Automated test script
└── Sample_Files/             # Sample vector graphics files
    ├── OWL1.CGM              # Sample HiJaak CGM test file (1994)
    ├── BUTRFLY.WMF           # Sample WMF file
    └── sample.wmf            # Sample WMF file

Troubleshooting

Graphics Rendering Issues

All black rendering?

  • File may use HiJaak vendor extensions (Element 23)
  • Check color selection mode: indexed (0) vs direct RGB (1)
  • Verify that vvi_viewer.py:651-664 is handling Element 23
  • Open the CGM file and check for non-standard elements

Colors wrong?

  • Check color selection mode (indexed vs direct RGB)
    • Mode set by Picture Descriptor element (class 2, id 2)
  • Verify color precision (8-bit vs 16-bit)
    • Parser converts 16-bit to 8-bit: vvi_viewer.py:614-617
  • Color table may not be initialized (check element class 5, id 34)

Missing shapes or invisible fills?

  • Interior style may be set to Empty (4) or Hollow (0)
    • Check set_interior_style() calls in parser
  • Fill colors not being set properly
    • Look for Fill Colour element (class 5, id 23)
  • VDC extent may be incorrect
    • Check VDC EXTENT element (class 2, id 6)

Installation Issues

ModuleNotFoundError: No module named 'tkinter'

  • tkinter not included with your Python installation
  • See "Installing tkinter" section above
  • On Linux: sudo apt-get install python3-tk

ModuleNotFoundError: No module named 'PIL'

  • Pillow not installed
  • Run: pip install -r requirements.txt
  • Or: pip install pillow

GUI window doesn't appear

  • Check if X11/display server is running (Linux)
  • On WSL, install VcXsrv or use WSLg (Windows 11)
  • Verify tkinter installation: python -c "import tkinter; tkinter.Tk()"

File Format Issues

struct.error or parsing errors

  • File may be corrupted
  • File may use clear text encoding (not supported yet)
  • Check file starts with binary CGM header (not ASCII)

Unexpected end of file

  • CGM file truncated
  • Missing END METAFILE element
  • Parser stops at position where header extends beyond file

Development & Testing

Running Tests

The repository includes a test script:

bash test_features.sh

This script tests the SVG conversion with the included OWL1.CGM sample file.

Project Documentation

For developers working on this codebase:

  • CLAUDE.md - Architecture guide, design decisions, coding conventions
  • FEATURES.md - Feature implementation status
  • cgm_fileformat.md - Detailed CGM binary format specification with examples

Adding New CGM Elements

To add support for a new CGM element:

  1. Identify element class and ID from CGM spec
  2. Add parser logic in vvi_viewer.py:507-692 (GUI renderer)
  3. Add corresponding logic in cgm_to_svg.py:75-168 (SVG converter)
  4. Implement rendering in CGMRenderer and CGMSVGRenderer classes
  5. Test with sample files containing the element

Code Structure

  • Parser: Binary CGM parsing is in render_cgm_graphics() method
  • Renderer: Two implementations with same API
    • CGMRenderer (PIL-based, raster)
    • CGMSVGRenderer (pure Python, vector)
  • Coordinate transform: transform_coords() method handles VDC to screen mapping

Dependencies Used

Standard Library (no install needed):

  • tkinter - GUI framework (TCL/Tk binding)
  • struct - Binary data parsing
  • os - File system operations
  • sys - System operations
  • io - I/O operations

External (install via pip):

  • Pillow - Image rendering and manipulation

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Based on ISO/IEC 8632 CGM specification
  • Special thanks to the CGM format documentation community
  • HiJaak extensions reverse-engineered from file analysis
  • Sample file OWL1.CGM from 1994 HiJaak Pro software

Further Reading

  • ISO/IEC 8632-1:1999 - Computer graphics — Metafile for the storage and transfer of picture description information
  • MIL-D-28003/BASIC-1 - Military standard for CGM (with HiJaak extensions)
  • cgm_fileformat.md - Detailed format documentation in this repository

Authoring

Made with ❤️ by Reinaldo Torres — reyco2000@gmail.com

Co-Coded with Anthropic's Claude Code

See more on Youtube @ChipShift | GitHub

About

A python script to View and Convert WFM, CMG vintage file formats

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published