Skip to content

Anti-aliased line/circle rendering, grayscale PNG output, and Spring Boot-style actuator endpoints - #17

Closed
Grizaster wants to merge 13 commits into
GOODBOY008:mainfrom
Grizaster:main
Closed

Anti-aliased line/circle rendering, grayscale PNG output, and Spring Boot-style actuator endpoints#17
Grizaster wants to merge 13 commits into
GOODBOY008:mainfrom
Grizaster:main

Conversation

@Grizaster

Copy link
Copy Markdown

Overview

This PR improves rendering quality to match commercial alternatives (e.g. Labelary) by adding anti-aliasing for all line and circle primitives, and adds Spring Boot-style management endpoints to the HTTP server.

Rendering Improvements

Anti-aliased diagonal lines (^GD)

  • Thin lines (thickness ≤ 1): Replaced Bresenham (draw_line_segment_mut) with Xiaolin Wu's algorithm (draw_antialiased_line_segment_mut) for smooth edges
  • Thick lines (thickness > 1): Custom parallelogram fill with per-pixel coverage at the left and right edges. The previous draw_polygon_mut approach only drew the outline, not the filled shape

Anti-aliased circles (^GC)

  • Replaced draw_filled_circle_mut and the binary distance-check ring with a per-pixel coverage-based approach
  • Both inner and outer ring edges use a 1px-wide coverage ramp (distance ± 0.5) for smooth anti-aliased edges

Grayscale PNG output

  • Removed the binary threshold (pixel > 128 ? 255 : 0) from encode_png
  • PNG output is now 8-bit grayscale, preserving anti-aliasing from the renderer
  • Matches Labelary's default X-Quality: Grayscale output

Management Endpoints (Actuator)

Added Spring Boot-style actuator endpoints under /manage/:

Endpoint Description
GET /manage/health Health check with component status (diskSpace)
GET /manage/info Build info: app name, version, architecture, OS, timezone, language
GET /manage/env Filtered environment variables (LABELIZE_*, RUST_*, TZ, LANG, LC_ALL, PATH, HOME, HOSTNAME, USER, SHELL, TERM)
GET /manage/metrics Render metrics: total/preview/PDF/failed counts, average render time, uptime

Metrics are tracked via AtomicU64 counters and Instant timer. The existing /health endpoint is kept for backwards compatibility.

Dependencies

  • Added serde_json (optional, behind serve feature) for structured JSON responses

Files Changed

  • src/drawers/renderer.rs — anti-aliased line and circle rendering
  • src/images/monochrome.rs — grayscale PNG encoding (removed binary threshold)
  • src/main.rs — actuator endpoints, metrics tracking
  • Cargo.tomlserde_json dependency

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Labelize’s rendering pipeline to preserve anti-aliasing (by improving circle/diagonal-line rasterization and switching PNG output to grayscale), and extends the Axum HTTP server with Spring Boot-style /manage/* actuator endpoints that expose health/info/env/metrics.

Changes:

  • Added /manage/health, /manage/info, /manage/env, /manage/metrics endpoints and basic request/render timing counters in the serve HTTP server.
  • Refactored the renderer to expose draw_label_to_rgba, and implemented anti-aliased circle + diagonal-line drawing.
  • Changed PNG encoding from thresholded black/white to 8-bit grayscale; added serde_json behind the serve feature.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 6 comments.

File Description
src/main.rs Adds /manage/* endpoints, shared app state, and render/request metrics; switches HTTP PNG path to encode from an RGBA canvas.
src/images/monochrome.rs Changes PNG encoding to grayscale (L8) by removing the binarization threshold.
src/drawers/renderer.rs Introduces draw_label_to_rgba and implements anti-aliased circle and diagonal-line rendering.
Cargo.toml Adds optional serde_json and wires it into the serve feature.
Comments suppressed due to low confidence (1)

src/images/monochrome.rs:20

  • encode_png is publicly re-exported (src/lib.rs:20) and lives under images::monochrome, but it now encodes 8-bit grayscale (ExtendedColorType::L8) instead of a binary/monochrome image. That semantic change can break API expectations for downstream consumers who relied on 1-bit output.

Consider either (a) keeping the old thresholded encoder as encode_png_monochrome and introducing encode_png_grayscale, or (b) adding an explicit option/parameter to select the output mode.

pub fn encode_png(img: &RgbaImage, w: &mut impl Write) -> Result<(), LabelizeError> {
    let (width, height) = img.dimensions();
    let mut gray = image::GrayImage::new(width, height);

    for y in 0..height {
        for x in 0..width {
            let pixel = img.get_pixel(x, y);
            gray.put_pixel(x, y, image::Luma([pixel[0]]));
        }
    }

    let encoder = image::codecs::png::PngEncoder::new(w);
    use image::ImageEncoder;
    encoder
        .write_image(gray.as_raw(), width, height, image::ExtendedColorType::L8)
        .map_err(|e| LabelizeError::Encode(format!("PNG encode error: {}", e)))

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/main.rs Outdated
Comment thread src/main.rs
Comment thread src/main.rs
Comment thread src/main.rs Outdated
Comment thread src/main.rs
Comment thread src/drawers/renderer.rs
@GOODBOY008
GOODBOY008 self-requested a review July 14, 2026 02:08
@GOODBOY008 GOODBOY008 added the enhancement New feature or request label Jul 14, 2026
@GOODBOY008

Copy link
Copy Markdown
Owner

@Grizaster Thanks for your contributions. Pls fix the ci. I will take a look this feature.

Grizaster added 13 commits July 16, 2026 07:08
Preview mode was rendering at 72dpmm without scaling ZPL coordinates,
causing content to appear in the top-left corner at ~10% of canvas size.

Now uses 4x supersampling: scales all element coordinates/sizes by 4x,
renders at 4x dpmm, then downsamples with CatmullRom filter for smooth
anti-aliased edges. Output is grayscale (no binary thresholding) to
preserve anti-aliasing.
Adds /manage/health, /manage/info, /manage/env, /manage/metrics.
Tracks render counts, preview/pdf counts, avg render time, uptime.
Existing /health endpoint kept for backwards compatibility.
- Replace Bresenham line drawing with anti-aliased variants
  (draw_antialiased_line_segment_mut, draw_antialiased_polygon_mut)
- Remove binary threshold in encode_png: output 8-bit grayscale
  instead of 1-bit monochrome, preserving anti-aliasing edges
- Matches Labelary's default Grayscale output quality
- Thick diagonal lines (^GD t>1): manual parallelogram fill with AA edges
  instead of draw_antialiased_polygon_mut (which only draws outlines)
- Circle (^GC): per-pixel distance-based coverage for both inner and outer
  edges, producing smooth anti-aliased ring edges
- Remove preview mode (scale_label, supersampling) — no longer needed
  since normal rendering is now anti-aliased
- Remove preview_renders metric
- Clean up unused imports
- Update unit_png_encoder tests: assert grayscale passthrough instead
  of binary threshold behavior
- Fix clippy manual_clamp warnings: use clamp() instead of max().min()
- Increase dhlparceluk golden test tolerance from 5.5% to 6.0% to
  account for anti-aliasing pixel diff
- cargo fmt
- Fix avg_ms metric: remove erroneous 1000x multiplication (was already in ms)
- Increment failed_renders on all error paths (render, PNG encode, PDF encode)
- Filter secrets from /manage/env: exclude vars containing TOKEN, KEY,
  PASSWORD, SECRET, CREDENTIAL
- /manage/health: report real disk space via statvfs instead of hard-coded zeros
- Regenerate all testdata/diffs after rendering changes (per AGENTS.md)
- Add libc dependency for statvfs on Unix
@GOODBOY008

Copy link
Copy Markdown
Owner

@Grizaster This PR contains multiple features. Could you please split it into several smaller PRs?

@Grizaster Grizaster closed this Jul 16, 2026
@Grizaster

Copy link
Copy Markdown
Author

Closed in favor of two smaller PRs as requested:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants