Skip to content

Commit

Permalink
Move preview rendering to preview render engine
Browse files Browse the repository at this point in the history
Discard the QT image functionality in favor of Pillow's
  • Loading branch information
Tomer Shalev committed Feb 8, 2024
1 parent 02b7f4a commit 851c0ae
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 26 deletions.
6 changes: 5 additions & 1 deletion src/dymoprint/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,11 @@ def run():
max_width_px=max_payload_len_px,
min_width_px=min_payload_len_px,
)
render_context = RenderContext(height_px=dymo_labeler.height_px)
render_context = RenderContext(
background_color="white",
foreground_color="black",
height_px=dymo_labeler.height_px,
)

# print or show the label
if args.preview or args.preview_inverted or args.imagemagick or args.browser:
Expand Down
20 changes: 7 additions & 13 deletions src/dymoprint/gui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from PIL import Image, ImageQt
from PyQt6 import QtCore
from PyQt6.QtCore import QCommandLineOption, QCommandLineParser, QSize, Qt, QTimer
from PyQt6.QtGui import QColor, QIcon, QPainter, QPixmap
from PyQt6.QtGui import QIcon, QPixmap
from PyQt6.QtWidgets import (
QApplication,
QComboBox,
Expand Down Expand Up @@ -121,8 +121,8 @@ def init_connections(self):
self.tape_size_mm.currentTextChanged.connect(self.update_params)
self.min_label_width_mm.valueChanged.connect(self.update_params)
self.justify.currentTextChanged.connect(self.update_params)
self.foreground_color.currentTextChanged.connect(self.label_list.render_label)
self.background_color.currentTextChanged.connect(self.label_list.render_label)
self.foreground_color.currentTextChanged.connect(self.update_params)
self.background_color.currentTextChanged.connect(self.update_params)
self.label_list.renderPrintPreviewSignal.connect(self.update_preview_render)
self.label_list.renderPrintPayloadSignal.connect(self.update_print_render)
self.print_button.clicked.connect(self.print_label)
Expand Down Expand Up @@ -184,6 +184,10 @@ def update_params(self):
tape_size_mm: float = self.tape_size_mm.currentData()

self.dymo_labeler.tape_size_mm = tape_size_mm

# Update render context
self.render_context.foreground_color = self.foreground_color.currentText()
self.render_context.background_color = self.background_color.currentText()
self.render_context.height_px = self.dymo_labeler.height_px

self.label_list.update_params(
Expand All @@ -197,16 +201,6 @@ def update_params(self):
def update_preview_render(self, preview_bitmap):
qim = ImageQt.ImageQt(preview_bitmap)
q_image = QPixmap.fromImage(qim)

mask = q_image.createMaskFromColor(
QColor("255, 255, 255"), Qt.MaskMode.MaskOutColor
)
q_image.fill(QColor(self.background_color.currentText()))
p = QPainter(q_image)
p.setPen(QColor(self.foreground_color.currentText()))
p.drawPixmap(q_image.rect(), mask, mask.rect())
p.end()

self.label_render.setPixmap(q_image)
self.label_render.adjustSize()
self.info_label.setText(f"← {px_to_mm(preview_bitmap.size[0])} mm →")
Expand Down
23 changes: 20 additions & 3 deletions src/dymoprint/lib/render_engines/print_preview.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from PIL import Image, ImageOps
from PIL import Image, ImageColor, ImageOps

from dymoprint.lib.render_engines.margins import MarginsMode, MarginsRenderEngine
from dymoprint.lib.render_engines.render_context import RenderContext
Expand Down Expand Up @@ -28,6 +28,23 @@ def __init__(
min_width_px=min_width_px,
)

def render(self, context: RenderContext) -> Image.Image:
def _get_preview_bitmap(self, context: RenderContext):
label_bitmap = self.render_engine.render(context)
return ImageOps.invert(label_bitmap.convert("L"))
bitmap = ImageOps.invert(label_bitmap.convert("L")).convert("RGBA")
pixel_map = {
"black": context.foreground_color,
"white": context.background_color,
}
pixel_map = {
ImageColor.getcolor(k, "RGBA"): ImageColor.getcolor(v, "RGBA")
for k, v in pixel_map.items()
}
pixdata = bitmap.load()
width, height = bitmap.size
for x in range(0, width):
for y in range(0, height):
pixdata[x, y] = pixel_map[pixdata[x, y]]
return bitmap

def render(self, context: RenderContext) -> Image.Image:
return self._get_preview_bitmap(context)
4 changes: 3 additions & 1 deletion src/dymoprint/lib/render_engines/render_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@


class _RenderContextFieldName(Enum):
HEIGHT_PX = 1
BACKGROUND_COLOR = 1
FOREGROUND_COLOR = 2
HEIGHT_PX = 3


class RenderContext:
Expand Down
23 changes: 15 additions & 8 deletions src/dymoprint/lib/unicode_blocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,32 @@
LH = "▄"
FB = "█"
NB = "\xa0"
LS = "░"

assert UH == "\N{UPPER HALF BLOCK}"
assert LH == "\N{LOWER HALF BLOCK}"
assert FB == "\N{FULL BLOCK}"
assert NB == "\N{NO-BREAK SPACE}"
assert LS == "\N{LIGHT SHADE}"

BLACK_PIXEL = (255, 255, 255, 255)
WHITE_PIXEL = (0, 0, 0, 255)
TRANSPARENT_PIXEL = (0, 0, 0, 0)

dict_unicode = {
(255, 255): FB,
(0, 255): LH,
(255, 0): UH,
(0, 0): NB,
(BLACK_PIXEL, BLACK_PIXEL): FB,
(WHITE_PIXEL, BLACK_PIXEL): LH,
(BLACK_PIXEL, WHITE_PIXEL): UH,
(WHITE_PIXEL, WHITE_PIXEL): NB,
(BLACK_PIXEL, TRANSPARENT_PIXEL): LS,
}

dict_unicode_inverted = {
(255, 255): NB,
(0, 255): UH,
(255, 0): LH,
(0, 0): FB,
(BLACK_PIXEL, BLACK_PIXEL): NB,
(WHITE_PIXEL, BLACK_PIXEL): UH,
(BLACK_PIXEL, WHITE_PIXEL): LH,
(WHITE_PIXEL, WHITE_PIXEL): FB,
(BLACK_PIXEL, TRANSPARENT_PIXEL): LS,
}


Expand Down

0 comments on commit 851c0ae

Please sign in to comment.