From 610954f8000ae76e005e2a4d30f66a268553ba62 Mon Sep 17 00:00:00 2001 From: Philipp Klaus Date: Tue, 19 Sep 2017 12:49:00 +0200 Subject: [PATCH] brother_ql_create --red speedup (saving 90% CPU time) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dissection of the color into red, black, & white now takes part in the HSV color space (instead of HLS before). Pillow's built-in capabilities to convert RGB → HSV are now used. While the creation of --red labels still takes 16 times longer than the simple black/white ones, it is now 90% less time than before this commit. --- brother_ql/brother_ql_create.py | 12 ++++----- brother_ql/image_trafos.py | 46 +++++++-------------------------- 2 files changed, 16 insertions(+), 42 deletions(-) diff --git a/brother_ql/brother_ql_create.py b/brother_ql/brother_ql_create.py index 57b49ce..8b0eb8d 100755 --- a/brother_ql/brother_ql_create.py +++ b/brother_ql/brother_ql_create.py @@ -10,7 +10,7 @@ import PIL.ImageOps, PIL.ImageChops from brother_ql.raster import BrotherQLRaster from brother_ql.devicedependent import models, label_type_specs, ENDLESS_LABEL, DIE_CUT_LABEL, ROUND_DIE_CUT_LABEL from brother_ql import BrotherQLError, BrotherQLUnsupportedCmd, BrotherQLUnknownModel -from brother_ql.image_trafos import filtered_hls +from brother_ql.image_trafos import filtered_hsv try: stdout = sys.stdout.buffer @@ -104,18 +104,18 @@ def create_label(qlr, image, label_size, threshold=70, cut=True, dither=False, c im = new_im if red: - filter_h = lambda h: 255 if h < 60 or h > 240 else 0 - filter_l = lambda l: 255 if l < 220 else 0 + filter_h = lambda h: 255 if (h < 40 or h > 210) else 0 filter_s = lambda s: 255 if s > 100 else 0 - red_im = filtered_hls(im, filter_h, filter_l, filter_s) + filter_v = lambda v: 255 if v > 80 else 0 + red_im = filtered_hsv(im, filter_h, filter_s, filter_v) red_im = red_im.convert("L") red_im = PIL.ImageOps.invert(red_im) red_im = red_im.convert("1", dither=Image.NONE) filter_h = lambda h: 255 - filter_l = lambda l: 255 if l < 120 else 0 filter_s = lambda s: 255 - black_im = filtered_hls(im, filter_h, filter_l, filter_s) + filter_v = lambda v: 255 if v < 80 else 0 + black_im = filtered_hsv(im, filter_h, filter_s, filter_v) black_im = black_im.convert("L") black_im = PIL.ImageOps.invert(black_im) black_im = black_im.convert("1", dither=Image.NONE) diff --git a/brother_ql/image_trafos.py b/brother_ql/image_trafos.py index c994dee..05018b7 100644 --- a/brother_ql/image_trafos.py +++ b/brother_ql/image_trafos.py @@ -1,49 +1,23 @@ from PIL import Image import colorsys -def HLSColor(img): +def filtered_hsv(im, filter_h, filter_s, filter_v, default_col=(255,255,255)): """ https://stackoverflow.com/a/22237709/183995 """ - if isinstance(img,Image.Image): - img = img.convert('RGB') - r,g,b = img.split() - Hdat = [] - Ldat = [] - Sdat = [] - for rd,gn,bl in zip(r.getdata(),g.getdata(),b.getdata()) : - h,l,s = colorsys.rgb_to_hls(rd/255.,gn/255.,bl/255.) - Hdat.append(int(h*255.)) - Ldat.append(int(l*255.)) - Sdat.append(int(s*255.)) - r.putdata(Hdat) - g.putdata(Ldat) - b.putdata(Sdat) - return Image.merge('RGB',(r,g,b)) - else: - return None -def filtered_hls(im, filter_h, filter_l, filter_s, default_col=(255,255,255)): - hls_im = HLSColor(im) - - H, L, S = 0, 1, 2 - hls = hls_im.split() - mask_h = hls[H].point(filter_h) - mask_l = hls[L].point(filter_l) - mask_s = hls[S].point(filter_s) + hsv_im = im.convert('HSV') + H, S, V = 0, 1, 2 + hsv = hsv_im.split() + mask_h = hsv[H].point(filter_h) + mask_s = hsv[S].point(filter_s) + mask_v = hsv[V].point(filter_v) Mdat = [] - # for debugging: - #mask_h, mask_l, mask_s = hls_im.split() - seen = [] - for h, l, s in zip(mask_h.getdata(), mask_l.getdata(), mask_s.getdata()): - if (h, l, s) not in seen: - seen.append((h, l, s)) - #print((h, l, s)) - Mdat.append(255 if (h and l and s) else 0) + for h, s, v in zip(mask_h.getdata(), mask_s.getdata(), mask_v.getdata()): + Mdat.append(255 if (h and s and v) else 0) mask = mask_h mask.putdata(Mdat) - filtered_im = Image.new("RGB", hls_im.size, color=default_col) + filtered_im = Image.new("RGB", im.size, color=default_col) filtered_im.paste(im, None, mask) return filtered_im -