Tune print quality defaults: density 2, font 30pt, threshold 160
- Default density to thick (2) for bolder output - Default font size to 30pt for better readability - Add draw.fontmode="1" to disable antialiasing for crisp 1-bit text - Add ImageOps.autocontrast before thresholding images - Update web GUI defaults to match CLI
This commit is contained in:
@@ -157,17 +157,17 @@ def main() -> None:
|
||||
|
||||
p_text = sub.add_parser("text", help="Print text label")
|
||||
p_text.add_argument("text", nargs="+", help="Text to print")
|
||||
p_text.add_argument("--density", type=int, default=1, choices=[0, 1, 2],
|
||||
p_text.add_argument("--density", type=int, default=2, choices=[0, 1, 2],
|
||||
help="Print density: 0=light, 1=medium, 2=thick")
|
||||
p_text.add_argument("--copies", type=int, default=1, help="Number of copies")
|
||||
p_text.add_argument("--font-size", type=int, default=24, help="Font size in points")
|
||||
p_text.add_argument("--font-size", type=int, default=30, help="Font size in points")
|
||||
p_text.add_argument("--label-height", type=int, default=240,
|
||||
help="Label height in pixels (default: 240)")
|
||||
p_text.set_defaults(func=cmd_text)
|
||||
|
||||
p_image = sub.add_parser("image", help="Print image file")
|
||||
p_image.add_argument("path", help="Path to image file")
|
||||
p_image.add_argument("--density", type=int, default=1, choices=[0, 1, 2],
|
||||
p_image.add_argument("--density", type=int, default=2, choices=[0, 1, 2],
|
||||
help="Print density: 0=light, 1=medium, 2=thick")
|
||||
p_image.add_argument("--copies", type=int, default=1, help="Number of copies")
|
||||
p_image.set_defaults(func=cmd_image)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
from PIL import Image, ImageDraw, ImageFont, ImageOps
|
||||
|
||||
from fichero.printer import PRINTHEAD_PX
|
||||
|
||||
@@ -18,6 +18,7 @@ def prepare_image(img: Image.Image, max_rows: int = 240) -> Image.Image:
|
||||
log.warning("Image height %dpx exceeds max %dpx, cropping bottom", new_h, max_rows)
|
||||
new_h = max_rows
|
||||
img = img.resize((PRINTHEAD_PX, new_h), Image.LANCZOS)
|
||||
img = ImageOps.autocontrast(img, cutoff=1)
|
||||
img = img.point(lambda x: 1 if x < 128 else 0, "1")
|
||||
return img
|
||||
|
||||
@@ -31,12 +32,13 @@ def image_to_raster(img: Image.Image) -> bytes:
|
||||
return img.tobytes()
|
||||
|
||||
|
||||
def text_to_image(text: str, font_size: int = 24, label_height: int = 240) -> Image.Image:
|
||||
"""Render text in landscape, then rotate 90 degrees for label printing."""
|
||||
def text_to_image(text: str, font_size: int = 30, label_height: int = 240) -> Image.Image:
|
||||
"""Render crisp 1-bit text, rotated 90 degrees for label printing."""
|
||||
canvas_w = label_height
|
||||
canvas_h = PRINTHEAD_PX
|
||||
img = Image.new("L", (canvas_w, canvas_h), 255)
|
||||
draw = ImageDraw.Draw(img)
|
||||
draw.fontmode = "1" # disable antialiasing - pure 1-bit glyph rendering
|
||||
|
||||
font = ImageFont.load_default(size=font_size)
|
||||
|
||||
|
||||
@@ -287,8 +287,8 @@
|
||||
<textarea id="textInput" placeholder="Type your label text..." rows="2">Hello</textarea>
|
||||
<div class="range-row">
|
||||
<label>Font size</label>
|
||||
<input type="range" id="fontSize" min="10" max="72" value="24">
|
||||
<span id="fontSizeVal">24</span>
|
||||
<input type="range" id="fontSize" min="10" max="72" value="30">
|
||||
<span id="fontSizeVal">30</span>
|
||||
</div>
|
||||
<div class="preview-wrap">
|
||||
<canvas id="textPreview"></canvas>
|
||||
@@ -331,8 +331,8 @@
|
||||
<label>Density</label>
|
||||
<select id="density">
|
||||
<option value="0">Light</option>
|
||||
<option value="1" selected>Medium</option>
|
||||
<option value="2">Thick</option>
|
||||
<option value="1">Medium</option>
|
||||
<option value="2" selected>Thick</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="setting-item">
|
||||
@@ -663,7 +663,7 @@ function threshold(canvas) {
|
||||
for (let i = 0; i < px.length; i += 4) {
|
||||
// Grayscale via luminance
|
||||
const gray = 0.299 * px[i] + 0.587 * px[i + 1] + 0.114 * px[i + 2];
|
||||
const bw = gray < 128 ? 0 : 255;
|
||||
const bw = gray < 160 ? 0 : 255;
|
||||
px[i] = px[i + 1] = px[i + 2] = bw;
|
||||
px[i + 3] = 255;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user