Coloring Vectorizer is a standalone web application that converts PNG, JPG, JPEG, and WebP images into real SVG drawings for coloring. It generates independent, closed white regions with a black vector line-art layer on top, so the output can be clicked or tapped to fill areas with color.
The project does not depend on paid APIs or external vectorization services. Image processing runs on the server with PHP/GD, while the browser provides the upload UI, SVG preview, painting tools, batch workflow, and downloads.
- Converts
image/png,image/jpeg, andimage/webpuploads into SVG. - Accepts files up to 10 MB by default.
- Produces a white SVG background, individual
.coloring-regionpaths, and a black#line-artpath. - Keeps coloring regions closed, allowing tap-to-fill behavior without color leaking into neighboring regions.
- Preserves the original drawing style better by using connected white regions plus a black line-art mask.
- Includes a PHP API fallback endpoint for hosts that do not rewrite extensionless routes.
- Drag and drop an image into the single conversion panel.
- Select an image through the file picker.
- Preview the original image and the generated SVG side by side.
- Convert the current image using the active preset and slider values.
- Reset the workspace with the New image action.
- Switch between Single Conversion and Batch Conversion tabs.
- Select multiple images at once.
- Select or drag folders where supported by the browser.
- Filter invalid files before conversion.
- Display a batch table with original image name, output SVG name, size, status, and actions.
- Retry failed conversions individually.
- Remove pending or failed files from the batch.
- Download completed SVGs one by one.
- Download every completed SVG as a ZIP file.
- Generate ZIP files in the browser with a built-in no-compression ZIP writer.
- Add a custom prefix to generated SVG file names.
- Configure the ZIP download file name.
- Add an optional internal folder inside the ZIP.
- Enable Folder Mode to name outputs as
[Folder]-[File].svg. - Preserve folder structure inside the ZIP when folder mode is enabled.
- Sanitize unsafe filename characters before generating downloads.
The UI includes three conversion presets:
- Simplified: produces larger regions and lighter output for complex images or mobile-friendly coloring.
- Balanced: default mode for preserving thin gray lines and anti-aliased coloring pages.
- Detailed: keeps more detail with smaller regions and a higher threshold.
The conversion can be adjusted with these controls:
- Detail level: changes internal processing resolution and detail preservation.
- Outline sensitivity: controls thresholding between dark line art and light areas.
- Curve smoothing: smooths generated region boundaries.
- Line thickness: adjusts the black line-art stroke width.
- Minimum region size: ignores regions below the selected size to reduce tiny areas.
- Noise removal: applies blur-based noise reduction before thresholding.
- Path simplification: reduces path complexity.
- Maximum SVG points: limits generated region complexity.
- Close small gaps: applies morphological closing to connect small breaks in outlines.
- Invert black and white: flips threshold interpretation for inverted artwork.
- Vertical aspect ratio 9:16: pads the SVG viewBox for portrait output.
After conversion, the generated SVG can be edited directly in the browser:
- Click or tap any
.coloring-regionto apply the selected color. - Choose colors with the built-in color picker.
- Undo and redo painting operations.
- Keep the black line-art path above colored regions so outlines remain visible.
- Download the edited SVG with the current fills.
- Export the edited result as PNG through a browser canvas render.
- Zoom and pan the original image preview.
- Zoom and pan the converted SVG preview.
- Synchronize the original and SVG viewers to compare details at the same zoom and position.
- Includes English and Brazilian Portuguese interface translations.
- Uses JSON language files in
assets/lang/. - Allows switching language from the page header.
- Updates translated labels, placeholders, statuses, and batch messages dynamically.
The PHP backend performs the vectorization locally:
- Validates request method and upload errors.
- Checks the real MIME type with
finfo. - Enforces the upload size limit.
- Decodes the image safely with
imagecreatefromstring. - Resizes the image to a safe processing resolution based on detail level.
- Converts pixels to grayscale with contrast adjustment.
- Optionally reduces noise with a box blur.
- Thresholds pixels into a black-line mask.
- Optionally closes small gaps using dilation and erosion.
- Finds connected white regions and traces their contours.
- Simplifies and smooths region paths.
- Builds a black line-art path from horizontal runs.
- Returns JSON containing the SVG markup and region count.
- PHP 7.0 or newer.
- PHP extensions:
gdfileinfojsonmbstring
- A web server capable of executing PHP.
- Apache rewrite support is recommended for
/api/vectorize; otherwise use/api/vectorize.php.
No Node.js build step is required for the vectorizer itself.
Generated comparison/reference outputs used while tuning the vectorizer should not be committed. The local vectorizer/diferença/ directory is ignored by Git.
vectorizer/
├── index.html # Main UI
├── router.php # Local PHP development router
├── api/
│ ├── vectorize # Extensionless API entry or rewrite target, depending on server setup
│ └── vectorize.php # PHP vectorization endpoint
├── assets/
│ ├── css/style.css # Application styles
│ ├── js/app.js # Main UI, single conversion, batch conversion, downloads
│ ├── js/svg-editor.js # Region painting, undo, redo, SVG serialization
│ ├── js/zoom-viewer.js # Zoom and pan preview behavior
│ ├── js/color-picker.js # Color picker setup
│ ├── js/i18n.js # Translation manager
│ └── lang/
│ ├── en.json # English strings
│ └── pt-BR.json # Brazilian Portuguese strings
From the vectorizer directory, start PHP's built-in server:
php -S 127.0.0.1:8080 router.phpThen open:
http://127.0.0.1:8080/
router.php exists only for local development. It routes /api/vectorize to the PHP endpoint when using PHP's built-in server.
- Copy the full
vectorizer/directory to the public web root. - Confirm that
index.htmlis reachable in the browser. - Confirm that
api/vectorize.phpexecutes as PHP. - If the server supports rewrites, configure
/api/vectorizeto reach the same endpoint. - Open the deployed URL, for example:
https://example.com/vectorizer/
The app uses relative paths for CSS, JavaScript, language files, and API calls, so keep the directory contents together.
The application limit is 10 MB per image. Server-level PHP settings must also allow that size. Recommended values:
upload_max_filesize = 10M
post_max_size = 12M
memory_limit = 256M
file_uploads = OnThe backend currently raises the runtime memory limit to 512M and execution time to 180 seconds, but shared hosting providers may override those values.
To change the application upload limit:
- Update
MAX_UPLOAD_BYTESinapi/vectorize.php. - Update the frontend file-size validation in
assets/js/app.js. - Update user-facing text in
index.htmland translation files. - Update server PHP limits if necessary.
Endpoint:
POST /api/vectorize
Fallback endpoint:
POST /api/vectorize.php
Request body must be multipart/form-data with:
| Field | Type | Description |
|---|---|---|
image |
file | PNG, JPG/JPEG, or WebP image. |
detail |
integer, 1-100 | Detail level and internal resolution. |
threshold |
integer, 1-255 | Outline sensitivity. |
smoothing |
integer, 0-10 | Curve smoothing amount. |
strokeWidth |
integer, 1-10 | Line-art stroke thickness. |
minRegion |
integer, 10-2000 | Minimum colorable region size. |
noise |
integer, 0-10 | Noise removal amount. |
simplify |
integer, 0-12 | Path simplification amount. |
maxPoints |
integer, 500-12000 | Maximum SVG points budget. |
gapClose |
integer, 0-8 | Small-gap closing amount. |
invert |
boolean-like | Use 1 to invert black/white interpretation. |
portrait |
boolean-like | Use 1 to pad to a 9:16 viewBox. |
Successful response:
{
"svg": "<svg ...></svg>",
"regions": 42
}Error response:
{
"error": "Human-readable error message"
}Generated SVGs use this general structure:
<svg xmlns="http://www.w3.org/2000/svg" ...>
<rect fill="#ffffff" />
<g id="coloring-regions" fill="#ffffff" stroke="none">
<path id="region-1" class="coloring-region" d="... Z" fill="#ffffff" stroke="none" />
</g>
<path id="line-art" d="..." fill="#000000" stroke="#000000" pointer-events="none" />
</svg>For integration with another coloring app:
- Insert the SVG inline into the DOM.
- Select all
.coloring-regionelements. - On
click,pointerdown, ortouchstart, update the region'sfillcolor. - Keep
#line-artabove the regions and withpointer-events="none". - Store coloring state as
{ id, fill }pairs or serialize the edited SVG.
- Uploads are validated by real MIME type, not only extension.
- Uploaded filenames are not used by the backend.
- Images are decoded with GD from binary content.
- The SVG is generated from server-created paths and does not embed the original image.
- The backend returns JSON for validation, processing, and fatal PHP errors when possible.
- Batch ZIP generation happens in the browser from generated SVG text.
The browser preview happens before upload. If the server rejects the image, check PHP upload settings, upload_max_filesize, post_max_size, temporary directory permissions, and whether file_uploads is enabled.
This means the API returned HTML instead of JSON, usually because PHP produced a warning, fatal error, server error page, or rewrite fallback page. Test api/vectorize.php directly and inspect the server error log.
The server is executing PHP correctly, but the extensionless route or rewrite rule is not configured. Point the frontend to the fallback endpoint or configure the web server to route /api/vectorize to api/vectorize.php.
Use the Simplified preset, lower the detail level, raise memory_limit, or increase server execution time. The backend already scales processing resolution dynamically, but very large or complex images can still require more resources.
- The app is intentionally dependency-light and can run as static HTML/CSS/JS plus a PHP endpoint.
- The frontend uses plain JavaScript modules/files without a bundler.
- Keep generated SVG regions closed with
Zso the coloring behavior remains reliable. - When changing backend options, update both the frontend controls and API option parsing.
- When changing text, update both
assets/lang/en.jsonandassets/lang/pt-BR.json.