Image Converter Windows App
A local-first Windows image converter built with Rust for private, offline batch conversion.
Repository Links
GitHub: https://github.com/walujanle/image-converter-windows-app
GitLab: https://gitlab.com/walujanle/image-converter-windows-app
Download Links
Latest Release: https://links.leonardwalujan.eu.org/lw/image-converter-windows-app-latest
Latest Release Checksum (SHA-256): https://links.leonardwalujan.eu.org/lw/image-converter-windows-app-latest-checksum
Source Code: https://links.leonardwalujan.eu.org/lw/image-converter-windows-app-latest-source-code
Screenshots
-
Image Converter Windows App Screenshot 1 -
Image Converter Windows App Screenshot 2 -
Image Converter Windows App Screenshot 3 -
Image Converter Windows App Screenshot 4
Short Explanation
Image Converter Windows App is a portable desktop application for converting image files directly on a Windows computer. It exists for people who need to convert a folder full of images without uploading personal photos to an online service first.
It reads and writes JPG, PNG, WebP, AVIF, HEIC/HEIF, and TIFF, and it can also decode camera RAW files (DNG, CR2, NEF, ARW, PEF, SR2) through a bundled copy of dcraw. Around that sits the rest of the workflow: format and quality selection, resizing, cropping, filename rules, custom output folders, presets, per-file progress, and optional metadata preservation.
The main idea is simple. The photos stay on the machine. The app reads the local file, processes it locally, writes the result locally, and never needs a server to do any of that.
Project Goals
I started this out of curiosity about how image conversion actually works. I wanted to know how different formats store their data, how metadata like EXIF, XMP, IPTC, and ICC survives (or doesn’t) when moving between containers, and how far conversion performance could be pushed in Rust.
It also turned into a way to learn Rust from a whole application rather than from isolated examples. A complete tool forces you to deal with things a tutorial skips: conversion logic, metadata handling, file validation, UI state, database migrations, and release packaging all have to work together and keep working after each change.
The practical side matters too. Converting, renaming, resizing, and recompressing a large set of images by hand is slow and easy to get wrong. Putting those steps into one local tool makes the work faster and the output more predictable — consistent naming, a known format, and a tidier folder afterwards.
Tech Stack Used
- Rust for the application and the conversion engine
- Native Windows desktop application model
- Windows 10/11 64-bit target
- SQLite for portable settings and preset storage
- Rust Windows/MSVC target for the main application binary
- MinGW/GCC for rebuilding the bundled
dcrawRAW decoder when needed - CMD and PowerShell for the automated Windows release workflow
- Portable ZIP distribution with app-local runtime files
The app links against external C codecs and uses a fair number of Rust crates internally, but the list above is about the main technology choices rather than a dependency dump.
Features
Batch image conversion
The main Converter screen. Click + Select Files or drag images into the file list, pick an output format, and press Start Conversion. Each row shows its own live percentage and final status, so a failure is attached to the file that caused it instead of stopping the run.
Supported input and output formats
The format selector in the options panel. Output can be JPG, PNG, WebP, AVIF, HEIC, or TIFF. Input covers those same formats plus camera RAW (DNG, CR2, NEF, ARW, PEF, SR2) — 15 file extensions in total.
Simple and Advanced modes
The toggle in the top header while the Converter tool is active. Simple mode reduces quality to four buttons (Low, Medium, High, Ultra) and hides the rest. Advanced mode exposes the quality slider, encode intent, output location, resize, crop, filename rules, and batch size. Each mode keeps its own file queue and settings, so switching back and forth does not wipe what you had loaded.
Quality and lossless controls
The options panel. JPG, WebP, AVIF, and HEIC use a 1–100 quality value that is passed straight through to the encoder, so 100 means the format ceiling for all four. WebP and HEIC also have a lossless checkbox, which hides the quality control when enabled. PNG has an optional Optimize PNG setting, off by default because it is CPU-heavy on large batches. TIFF is written losslessly and has no quality control.
Encode Intent
Next to the quality slider in Advanced mode, for the lossy formats. It answers a question quality alone can’t: what is this file for?
Balanced— the default, for everyday conversion.Archive— full chroma where the format allows it, slowest and smallest encoder settings, WebP switching to near-lossless at 95 and above.Social— subsampled chroma, faster encoding, quality capped at 90, and GPS coordinates plus camera and lens serial numbers stripped from the metadata.
The Social cap exists because upload platforms re-encode what they receive, so bytes spent above roughly 90 are thrown away before anyone sees the image. The cap is shown next to the slider as an arrow to the effective value rather than applied silently.
Resize and crop
Advanced mode. Resize takes a width and height with an optional aspect-ratio lock, and picks its filter automatically — Mitchell when upscaling, Lanczos3 when downscaling. Crop removes a percentage from the top, bottom, left, and right, and runs before the resize so the final dimensions reflect both.
Filename and output organization
Advanced mode. A custom output folder, a filename prefix, find-and-replace on the name, an automatic resolution suffix, and sequential numbering. There is also an optional File List section that writes a dataset_log.txt next to the output listing the generated filenames, grouped per output folder and numbered incrementally so a second run does not overwrite the first list.
Metadata preservation
The Keep Metadata option in the converter, off by default. When enabled, the app preserves EXIF, XMP, IPTC, and ICC in whichever form the target container supports, and adds OS-readable projections where Windows Properties reads a narrower subset than tools like ExifTool. That is why camera, GPS, lens, and author fields still show up in Windows file properties for formats that would otherwise look empty there. ICC colour profiles can be carried across separately to keep colour appearance consistent.
RAW metadata handling
Part of the metadata pipeline. For TIFF-like RAW files the app walks the IFD chain for embedded metadata and also picks up .xmp and .iptc sidecar files when they exist. Each RAW output route is tracked individually — RAW to PNG, AVIF, and TIFF are verified for both sidecar and embedded-only sources, and RAW to JPG, HEIC, and WebP are part of the protected stable set — because cameras and containers expose metadata differently enough that a single generic path would not hold.
Presets
The preset panel and the Preset Manager. Save a full set of conversion settings, reload recent or pinned presets, search by name or format, and group presets into folders. The encode intent is saved with the preset.
Settings backup and restore
The Backup and Restore buttons in the header. They export and import the SQLite database holding settings and presets, which is the practical way to move a configured setup to another machine.
Icon Generator
A separate tool in the top tool switcher. It takes one source image and produces Windows ICO, web favicon, or Android icon packages, written out as ZIP files to a folder you choose.
Portable settings
Stored in a data folder next to the executable, in SQLite with write-ahead logging. Saves are transactional, and the folder travels with the app when the portable folder is moved.
How It Works
Converting one file runs through a fixed sequence: check the file size against a 256 MB cap, check the extension against the whitelist and the magic bytes against the real signature, read the file once into memory, prepare metadata if Keep Metadata or an ICC transfer applies, decode, correct EXIF orientation, apply crop, apply resize, encode to the target format, embed metadata, verify it survived, and only then publish the result.
Everything is written to a temporary file first, placed in the output directory alongside the final name. Only after the output and its requested metadata check out does that temp file become the real one, and an existing file is replaced rather than deleted first. If encoding or verification fails, the temp file is removed and whatever was already there is left untouched.
A few limits sit around that pipeline. Each file gets a five-minute deadline, checked between stages, so a file that will never finish cannot hold up the queue. Conversions run in parallel up to twice the CPU core count. A failure stays with the file that caused it, so one unreadable image does not take the rest of the batch down with it.
Installation Guide
For normal users:
- Download the latest portable ZIP from the download link above.
- Optional: compare the SHA-256 checksum against the checksum link.
- Extract the ZIP into a folder you control, for example
Documents\Apps\Image Converter Windows App. - Run
image-converter-windows-app.exe. - Keep the
datafolder next to the executable if you want settings and presets to stay with the app.
Keep the whole folder together. The executable loads heif.dll, which in turn needs libx265.dll and libde265.dll, so moving the EXE out on its own breaks HEIC support. The app checks for this at startup and reports it in the status bar instead of failing halfway through a batch.
If Windows SmartScreen appears, only continue when the file came from the official download source. The app ships as an unsigned portable executable, so some systems will warn about it.
For developers:
-
Use Windows 10/11 64-bit.
rust-toolchain.tomlpins the compiler version, so rustup fetches the right one automatically. -
The main application builds for the Windows MSVC target. The release bundle uses the
x64-windowsvcpkg triplet and copies the MSVC runtime DLLs. -
Install Visual Studio 2022 Build Tools with the C++ build tools and Windows SDK. These provide the MSVC linker the Rust target needs, and the compiler any vcpkg port that builds from source needs.
-
Install MinGW/GCC and make sure
gccis inPATH. The release script uses it to rebuilddcraw.exefromdcraw\dcraw.cwhen the existing executable or its hash file is missing or stale. -
Install Git and CMake, which the standard vcpkg workflow depends on.
-
Install a standalone vcpkg folder and bootstrap it:
git clone https://github.com/microsoft/vcpkg.git C:\vcpkg C:\vcpkg\bootstrap-vcpkg.bat -
Install the required ports with the same
x64-windowstriplet the release script expects. Run these from the vcpkg folder, not the project root — runningvcpkg installinside the project uses manifest mode and installs into a local folder the release script does not read:vcpkg install libheif[hevc]:x64-windows vcpkg install dav1d:x64-windows vcpkg install pkgconf:x64-windows -
Set
VCPKG_ROOTto the vcpkg folder. For manual Cargo commands, also set:$env:PKG_CONFIG = "$env:VCPKG_ROOT\installed\x64-windows\tools\pkgconf\pkgconf.exe" $env:PKG_CONFIG_PATH = "$env:VCPKG_ROOT\installed\x64-windows\lib\pkgconfig" $env:PATH = "$env:VCPKG_ROOT\installed\x64-windows\bin;$env:PATH" -
Run the usual development checks. The
PATHentry above is not optional for tests — the test binary importsheif.dllanddav1d.dlldirectly and will fail withSTATUS_DLL_NOT_FOUNDbefore a single test runs without them:cargo check cargo test --lib cargo clippy --all-targets -- -D warnings cargo run -
For a portable release bundle, run
build_release_windows.bat. It runs formatting, tests, and clippy, verifies or rebuildsdcraw, builds the release binary, collects the DLLs, and produces the ZIP and its SHA-256 checksum. The DLL collection step fails closed: if a required file is missing after copying, packaging aborts rather than producing a ZIP that only runs on the build machine.
set PUBLISHER=Your Publisher Name
build_release_windows.bat
There are two separate native toolchains involved on Windows: the Rust application uses the MSVC target with vcpkg x64-windows, while the optional dcraw rebuild path uses MinGW/GCC through the gcc command.
A plain cargo build --release only produces the executable in target\release. To run that bare EXE outside the release folder you have to copy the HEIC/AVIF and MSVC runtime DLLs beside it yourself. RAW support also requires dcraw.exe and dcraw.exe.sha256 to exist in the repository root before compiling, because the app embeds the decoder into the executable and extracts it at runtime rather than looking for a sidecar. Those two files are gitignored, so a fresh clone will not compile until they are generated — either with the gcc command or by running the release script, which does it automatically.
Limit Problems
- The official build targets Windows 10/11 64-bit only.
- Very large images use a lot of memory. The pipeline reads each source file fully into RAM with no streaming, and resizing needs both a source and a destination buffer, so a 100 MP image can cost several hundred megabytes on its own.
- Input is capped at 256 MB per file and 16384×16384 pixels.
- Each file has a five-minute conversion deadline and there is no retry.
- PNG optimization is optional and off by default because it is slow and CPU-heavy.
- RAW support depends on the bundled decoder and on how each camera writes its files. The
dcrawsubprocess is not sandboxed; its bytes are SHA-256 verified, but that guards against tampering, not against a malformed file exploiting the parser. - Metadata visibility varies between Windows Properties, professional metadata tools, and other operating systems.
- WebP, AVIF, and HEIC have no native IPTC support, so IPTC is dropped for those outputs.
- AVIF cannot embed ICC profiles, a limitation of the
ravifencoder. - ICC profiles are copied verbatim, never converted. A Display-P3 source sent somewhere that assumes sRGB will look desaturated; real colour management is not implemented.
- Quality numbers are passed to each encoder unchanged, and the intent settings are reasoned defaults rather than measured ones. No perceptual metric verifies that quality 80 looks equivalent across formats.
- Unsigned portable builds can trigger Windows SmartScreen warnings.
License
Image Converter Windows App is released under the GNU General Public License v3.0 or later.
You can study, modify, and redistribute it under the GPL terms. The release bundle also ships third-party codec and runtime components — libheif and libde265 under LGPL-3.0, x265 under GPL-2.0+, dav1d under BSD-2-Clause, and dcraw under Dave Coffin’s own terms — so their licenses apply to those parts.
Latest Projects
Image Converter Web App
A browser-native local-first image converter built with React, TypeScript, Web Workers, and a Rust/WebAssembly npm engine.
Image Converter WASM
A Rust WebAssembly image conversion package for browser and Node.js runtimes, published as an npm package.
Test
Test