Comic artist canvas tool — pre-processing and post-processing for Webtoon-style publishing.
Platemaker handles both ends of the comic-art workflow: generating canvas templates with margin guides before drawing, and scaling + slicing finished artwork into upload-ready panels. It is designed around the Webtoon vertical-scroll format (800 px wide, 1280 px-high slices) but is architecturally extensible to other formats.
This repository contains libplatemaker (the core processing library) and the platemaker CLI binary. The Qt GUI lives in a separate repository and links against libplatemaker as a shared library.
For requirements, data models, pipeline details and the roadmap see the specification wiki — checked out here as a
submodule at docs/specification/, so git clone --recurse-submodules brings it with the code.
docs/SPECIFICATION.md maps the old section numbers to their new pages.
platemaker/
├── CMakeLists.txt # Root — finds dependencies, adds sub-projects
├── CMakePresets.json # Presets: linux-release, linux-debug, mingw-release, mingw-debug, …
├── cmake/
│ └── install.sh.in # Shell install-script template (generated by CMake)
├── lib/ # libplatemaker — Core + Infrastructure
│ ├── cmake/ # CMake package config template
│ ├── include/platemaker/
│ │ ├── models/ # Shared data types (CanvasProfile, Workspace, …)
│ │ ├── core/ # Pipeline components (Scaler, ScaledStrip, MarginCropper, …)
│ │ └── infrastructure/ # IO + caching (ImageIO, WorkspaceSerializer, ThumbnailCache)
│ └── src/ # Implementation files (mirrors include/ structure)
├── cli/ # platemaker binary — links libplatemaker
├── tests/
│ ├── lib-unit-tests/ # GoogleTest C++ unit tests for libplatemaker
│ ├── lib-fault-tests/ # its error paths, by making libvips/libarchive/libc calls fail (Linux only)
│ └── cli-tests/ # pytest-based Python integration tests for the CLI
└── docs/
├── SPECIFICATION.md # index: old section numbers -> wiki pages
├── specification/ # submodule: the specification wiki
├── CHEATSHEET.md
├── CODING_STYLE.md
└── TODO.md
| Tool | Version | Notes |
|---|---|---|
| CMake | 3.25+ | Presets format v6 |
| Git | any | |
| Python 3 | any | Only for CLI integration tests |
Tools to install:
-
Visual Studio 2022 — select the "Desktop development with C++" workload.
This installs: MSVC compiler, CMake, Ninja, Windows SDK.
No package manager needed. libvips, nlohmann-json, and GoogleTest are all fetched automatically by CMake on the first configure.
Optional (for CLI tests):
# Python 3 from https://www.python.org — check "Add Python to PATH"
pip install -r tests\cli-tests\requirements.txtTools to install:
-
MSYS2 — installs to
C:\msys64by default. -
In the MSYS2 MinGW64 terminal, install the required packages:
pacman -S \
mingw-w64-x86_64-gcc \
mingw-w64-x86_64-ninjalibvips (the slim prebuilt "web" build), nlohmann-json and GoogleTest are all fetched
automatically by CMake — no pacman packages needed for them. In particular MinGW no longer uses
MSYS2's mingw-w64-x86_64-libvips, so no PKG_CONFIG_PATH is required either.
Required PATH entry: add C:\msys64\mingw64\bin to your Windows system PATH.
This makes gcc, g++ and ninja available in any terminal, and provides the MinGW runtime DLLs
(libstdc++, libgcc, libwinpthread) at run time. The libvips DLLs come from the fetched web
build (copied next to the binaries at build time), not from PATH.
Tip: The MSYS2 installer offers to add itself to PATH automatically — accept that, then also add
C:\msys64\mingw64\binmanually if it was not added.
Tested on Ubuntu 22.04 LTS (native and inside WSL 2).
sudo apt update
sudo apt install -y \
build-essential cmake ninja-build pkg-config git \
libvips-dev \
python3 python3-pip
pip install -r tests/cli-tests/requirements.txtnlohmann-json and GoogleTest are fetched automatically from source if the system packages (nlohmann-json3-dev, libgtest-dev) are not installed. Installing them via apt is optional but speeds up the first configure.
A native debugger is useful for crashes and hangs — e.g. attaching to a stuck process to capture a stack trace. Install the one that matches how you build:
| Toolchain | Debugger | Install |
|---|---|---|
| MinGW (MSYS2) | GDB — reads MinGW's DWARF symbols | pacman -S mingw-w64-x86_64-gdb |
| Linux / WSL2 | GDB | sudo apt install gdb |
| MSVC | Visual Studio debugger (already installed with VS) — reads PDB, not DWARF | — |
GDB is the right tool for MinGW/Linux builds; the Visual Studio debugger only understands MSVC's PDB symbols, so use GDB for anything built with
g++.
Build with a debug preset (-g symbols) for readable stacks. To dump every thread's stack
of an already-running (e.g. wedged) process:
gdb -p <pid> -batch -ex "thread apply all bt"Download the pre-built package for your platform from the Releases page.
Every release archive ships a matching <archive>.sha256 sidecar, and GitHub shows the SHA-256 next to
each asset. Use either to confirm your download is intact and untampered.
Windows (PowerShell) — print the hash and compare it to the .sha256 file (or the hash GitHub shows):
Get-FileHash platemaker-cli-0.3.1-windows-mingw-release.zip -Algorithm SHA256Linux / MSYS2 — -c checks the archive against its sidecar automatically (coreutils format):
sha256sum -c platemaker-cli-0.3.1-linux-x86_64-release.tar.gz.sha256
# → platemaker-cli-0.3.1-linux-x86_64-release.tar.gz: OKBuild provenance — proof GitHub built it from this repo. Every release archive carries a GitHub build-provenance attestation: GitHub vouches that the file was produced by this repository's release workflow and records the exact source commit. Stronger than a checksum — you don't have to trust a hash we published.
gh attestation verify platemaker-cli-0.4.0-windows-mingw-release.zip --repo ShadobaDev/PlateMaker
# → ✓ Verification succeeded! (digest matches, built by this repo's release.yml at the tagged commit)No tools? Open the repo's Attestations page in a browser: each entry is a GitHub-verified build showing the file it covers (name + SHA-256), the source commit, and the workflow — GitHub confirming "this archive was built here, from this commit." Match that SHA-256 against your download's.
VirusTotal (no upload needed). VirusTotal identifies files by their SHA-256, so you can look up a scan
by hash: paste the archive's SHA-256 into the search box at virustotal.com,
or open https://www.virustotal.com/gui/file/<sha256> directly. If the file has been scanned, its report
appears; a release's notes may also link the report.
The archives are unsigned, so Windows may warn on the
.exeinside (SmartScreen/ "unknown publisher"). That is expected — the checksum and VirusTotal checks above are how you verify the download instead.
Each platform/build-type ships two archives — a dev package (to link against)
and a cli package (to run the platemaker-cli tool). <type> is release or debug.
| Package | File | Contents |
|---|---|---|
| Linux dev | platemaker-dev-<ver>-linux-x86_64-<type>.tar.gz |
libplatemaker.so + headers + CMake config |
| Linux cli | platemaker-cli-<ver>-linux-x86_64-<type>.tar.gz |
platemaker-cli + libplatemaker.so |
| Windows MinGW dev | platemaker-dev-<ver>-windows-mingw-<type>.zip |
libplatemaker.dll + headers + CMake config + runtime DLLs |
| Windows MinGW cli | platemaker-cli-<ver>-windows-mingw-<type>.zip |
platemaker-cli.exe + all runtime DLLs |
The Linux packages contain only Platemaker's own binaries — libvips and its
dependencies must be installed separately (see below). The Windows MinGW packages are
self-contained: all required DLLs are bundled in bin/.
libplatemaker.so links dynamically against libvips. Install it before using the package:
# Ubuntu / Debian
sudo apt install libvips-dev
# Fedora / RHEL
sudo dnf install vips-devel
# Arch Linux
sudo pacman -S libvipslibvips itself pulls in a chain of transitive dependencies (GLib, libjpeg, libpng, libwebp, libtiff, libheif, …). The apt/dnf/pacman package handles all of these automatically.
No other system packages are required — nlohmann/json is a private dependency whose types do not appear in the public API, so consumers do not need its headers.
None. All required DLLs are in the bin/ directory of the ZIP.
Make bin/ visible to Windows' DLL loader by doing one of the following:
- Copy the contents of
bin/next to your.exe. - Add the
bin/directory to yourPATH(convenient for development). - Use the CMake snippet below — it copies the DLLs automatically at build time.
Extract the archive and configure your project with CMAKE_PREFIX_PATH:
find_package(platemaker CONFIG REQUIRED)
target_link_libraries(my-app PRIVATE Platemaker::platemaker)
# Windows: copy libplatemaker.dll and its runtime DLLs next to the executable
if(WIN32)
add_custom_command(TARGET my-app POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"$<TARGET_FILE_DIR:Platemaker::platemaker>"
"$<TARGET_FILE_DIR:my-app>"
COMMENT "Copying platemaker runtime DLLs"
VERBATIM
)
endif()At configure time, tell CMake where the extracted package lives:
# Linux
cmake -B build -DCMAKE_PREFIX_PATH="/path/to/platemaker-dev-0.2.1-linux-x86_64-release"
# Windows (PowerShell)
cmake -B build -DCMAKE_PREFIX_PATH="C:/path/to/platemaker-dev-0.2.1-windows-mingw-release"CMake caches CMAKE_PREFIX_PATH, so you only need to pass it once per build directory.
| Platform | Runtime requirement | Provided by package |
|---|---|---|
| Linux x86_64 | libvips.so.42 + transitive deps |
No — install via package manager |
| Windows MinGW | vips DLLs, GLib, GCC runtime | Yes — bundled in bin/ |
Preset names follow
platform-buildtype, so the build type is explicit:linux-release,linux-debug,mingw-release,mingw-debug(pluslinux-asanfor local sanitizer runs,msvc-release/msvc-debug). For a copy-paste command list see docs/CHEATSHEET.md.
Open any PowerShell (MSYS2 environment variables must be set — see above):
cmake --preset mingw-release
cmake --build --preset mingw-release
ctest --preset mingw-release
# Debug build
cmake --preset mingw-debug
cmake --build --preset mingw-debugcmake --preset linux-release
cmake --build --preset linux-release
ctest --preset linux-release
# Debug
cmake --preset linux-debug
cmake --build --preset linux-debug
# Debug + AddressSanitizer (local only, not packageable)
cmake --preset linux-asan
cmake --build --preset linux-asanOpen Developer PowerShell for VS 2022. The GUI links with MinGW, so MSVC is for standalone CLI / testing only — an MSVC-built lib mismatches MinGW name mangling.
cmake --preset msvc-release
cmake --build --preset msvc-release
ctest --preset msvc-releaseEach build produces two archives, split by CPack component group:
| Archive | Contents | For |
|---|---|---|
platemaker-dev-<ver>-<sys>-<type> |
headers + CMake config + import lib + shared lib + runtime DLLs (Windows) | linking against the library (e.g. the Qt GUI) |
platemaker-cli-<ver>-<sys>-<type> |
platemaker-cli + a self-contained copy of the runtime |
running the CLI |
<type> is release or debug; debug archives keep their symbols (no strip).
There are two ways to produce them. Both run the same install rules (including the MinGW DLL pruning that bundles only libvips' actual runtime-dependency closure):
cmake --workflow --preset dist-<platform>-<type> |
cmake --install <build-dir> |
|
|---|---|---|
| Purpose | Cut release artifacts | Install locally for GUI development |
| Output | Two versioned archives in dist/ |
Loose directory tree in install/<preset>/ |
| Steps | configure → build → package, in one command | reuses your build tree; you cmake --build first |
| When | Publishing to GitHub Releases | Day-to-day: point the Qt GUI at install/<preset>/ |
In short: --install gives you a folder; --workflow runs the whole
configure → build → package waterfall and zips the result.
# Windows MinGW
cmake --workflow --preset dist-mingw-release
# → dist/platemaker-dev-0.2.1-windows-mingw-release.zip
# → dist/platemaker-cli-0.2.1-windows-mingw-release.zip
# …and dist-mingw-debug for the debug variants# Linux
cmake --workflow --preset dist-linux-release
# → dist/platemaker-dev-0.2.1-linux-x86_64-release.tar.gz
# → dist/platemaker-cli-0.2.1-linux-x86_64-release.tar.gz
# …and dist-linux-debug for the debug variantsThe dist-* presets build without the tests, in build/dist-<platform>-<type>. They install where
the development presets do (install/<platform>-<type>/). scripts/make_release.ps1 (Windows) and
scripts/make_release.sh (Linux) run the chosen workflows and install each result.
To re-package an existing build without rebuilding: cpack --preset <platform>-<type>
(e.g. cpack --preset mingw-release).
Installs an already-built tree to install/<preset>/ for direct use while developing
the Qt GUI. Configure and build first, then install:
# Windows MinGW
cmake --preset mingw-debug
cmake --build --preset mingw-debug
cmake --install build/mingw-debug
# → install/mingw-debug/ (set PLATEMAKER_DIR to this in Qt Creator)# Linux — note the build dir lives under $HOME, not ./build
cmake --preset linux-release
cmake --build --preset linux-release
cmake --install ~/build/platemaker/linux-release
# → install/linux-release/About
--config: it matters only for multi-config generators (Visual Studio / MSVC), where one build tree holds both Debug and Release — e.g.cmake --install build/msvc-release --config Release. Single-config generators (Ninja — MinGW and Linux) bake the build type in at configure time, so--configis ignored there; the preset name already pins it.
cmake --install writes all components (dev + cli) into one tree:
install/<preset>/
bin/
platemaker.dll Windows runtime (MinGW: libplatemaker.dll)
platemaker-cli[.exe] the CLI tool
libvips*.dll … runtime DLLs (MSVC: full vips package; MinGW: pruned to libvips' actual dependency closure)
lib/
libplatemaker.dll.a MinGW import library
platemaker.lib MSVC import library
libplatemaker.so Linux shared library (+ .so.0 / .so.0.2.1 symlinks)
lib/cmake/platemaker/
platemaker-config.cmake
platemaker-config-version.cmake
platemaker-targets.cmake
platemaker-targets-<config>.cmake per-config (debug/release) import info
include/platemaker/ all public headers
(The packaged archives split this tree: dev = everything except the CLI; cli = the CLI + a copy of the runtime libs.)
The recommended pattern tries a local dev package first, then falls back to an automatic download from GitHub Releases. Add the block below to your CMakeLists.txt, then point CMake at your local install via the PLATEMAKER_DIR cache variable — no paths hardcoded in source.
# ─── platemaker ────────────────────────────────────────────────────────────────
# Discovery order:
# 1. PLATEMAKER_DIR cache variable — explicit local dev package (set once, cached)
# 2. find_package — system install or CMAKE_PREFIX_PATH
# 3. FetchContent — downloads pre-built package from GitHub Releases
# ───────────────────────────────────────────────────────────────────────────────
set(PLATEMAKER_VERSION "0.2.1")
set(PLATEMAKER_DIR "" CACHE PATH "Path to a local platemaker dev package")
if(PLATEMAKER_DIR)
list(PREPEND CMAKE_PREFIX_PATH "${PLATEMAKER_DIR}")
endif()
find_package(platemaker CONFIG QUIET)
if(NOT platemaker_FOUND)
include(FetchContent)
string(TOLOWER "${CMAKE_BUILD_TYPE}" _pm_type)
if(NOT _pm_type)
set(_pm_type "release")
endif()
if(WIN32)
set(_pm_archive "platemaker-dev-${PLATEMAKER_VERSION}-windows-mingw-${_pm_type}.zip")
else()
set(_pm_archive "platemaker-dev-${PLATEMAKER_VERSION}-linux-x86_64-${_pm_type}.tar.gz")
endif()
FetchContent_Declare(
platemaker_pkg
URL "https://github.com/ShadobaDev/PlateMaker/releases/download/v${PLATEMAKER_VERSION}/${_pm_archive}"
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
FetchContent_MakeAvailable(platemaker_pkg)
FetchContent_GetProperties(platemaker_pkg SOURCE_DIR _pm_src)
file(GLOB _pm_dir LIST_DIRECTORIES true "${_pm_src}/platemaker-dev-*")
list(GET _pm_dir 0 _pm_dir)
list(PREPEND CMAKE_PREFIX_PATH "${_pm_dir}")
find_package(platemaker CONFIG REQUIRED)
endif()
target_link_libraries(${PROJECT_NAME} PRIVATE Platemaker::platemaker)
# Windows: copy platemaker.dll and all libvips runtime DLLs next to the executable
if(WIN32)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"$<TARGET_FILE_DIR:Platemaker::platemaker>"
"$<TARGET_FILE_DIR:${PROJECT_NAME}>"
COMMENT "Copying platemaker runtime DLLs"
VERBATIM
)
endif()Set PLATEMAKER_DIR once on the command line — CMake caches it for subsequent configures:
# Windows
cmake -B build -DPLATEMAKER_DIR="C:/path/to/platemaker-dev-0.2.1-windows-mingw-release"# Linux
cmake -B build -DPLATEMAKER_DIR="/path/to/platemaker-dev-0.2.1-Linux-x86_64"If PLATEMAKER_DIR is not set and platemaker is not found on the system, CMake automatically downloads the correct release archive from GitHub Releases during configure.
The library has an embedded RPATH of $ORIGIN/../lib, so executables installed alongside it find libplatemaker.so automatically. During development (running from the build tree without installing), point the loader at the package manually:
export LD_LIBRARY_PATH="/path/to/platemaker-dev-0.2.1-linux-x86_64-release/lib:$LD_LIBRARY_PATH"
./my-app| Configure / build / test preset | Platform | Type | Notes |
|---|---|---|---|
linux-release |
Linux / WSL2 | Release | libvips from apt; others auto-fetched |
linux-debug |
Linux / WSL2 | Debug | full symbols, no sanitizer (packageable) |
linux-asan |
Linux / WSL2 | Debug | + ASan/UBSan — local only, not packaged |
linux-coverage |
Linux / WSL2 | Debug | + --coverage, for gcovr (CI's coverage job) — not packaged |
mingw-release |
Windows MinGW | Release | libvips from MSYS2; others auto-fetched |
mingw-debug |
Windows MinGW | Debug | full symbols |
msvc-release / msvc-debug |
Windows MSVC | Release / Debug | secondary — all deps auto-fetched |
The same names work for cmake --preset, cmake --build --preset, ctest --preset
and cpack --preset.
| Workflow preset | Steps | Produces (in dist/) |
|---|---|---|
dist-linux-release |
configure → build → package (TGZ) | platemaker-{dev,cli}-…-linux-x86_64-release.tar.gz |
dist-linux-debug |
configure → build → package (TGZ) | …-linux-x86_64-debug.tar.gz (unstripped) |
dist-mingw-release |
configure → build → package (ZIP) | platemaker-{dev,cli}-…-windows-mingw-release.zip |
dist-mingw-debug |
configure → build → package (ZIP) | …-windows-mingw-debug.zip (unstripped) |
dist-msvc-release |
configure → build → package (ZIP) | …-windows-msvc-release.zip |
| Library | Licence | Linux (apt) | Windows |
|---|---|---|---|
| libvips | LGPL 2.1 | libvips-dev |
auto-fetched (MSVC) / MSYS2 pacman (MinGW) |
| nlohmann/json | MIT | nlohmann-json3-dev (optional) |
auto-fetched |
| GoogleTest | BSD 3-Clause | libgtest-dev (optional) |
auto-fetched |
| pytest | MIT | pip install pytest |
pip install pytest |
libplatemaker is distributed as a shared library — LGPL 3.0 requires that end users be able to relink against a modified version.
See docs/CODING_STYLE.md for naming conventions, Doxygen comment format, namespace-to-directory mapping rules, and file layout requirements.
libplatemaker— LGPL 3.0 (seeLICENSE.LGPL)platemaker-cli— GPL 3.0 (seeLICENSE.GPL)
Contributions are welcome. By opening a pull request you agree to the Contributor License Agreement.