brother_ql_create: enable creation of die-cut labels

This commit is contained in:
Philipp Klaus
2016-11-10 21:46:05 +01:00
parent 66a2e31442
commit e3e3236b4e
2 changed files with 67 additions and 42 deletions

View File

@@ -8,7 +8,7 @@ import numpy as np
from PIL import Image
from brother_ql.raster import BrotherQLRaster
from brother_ql.devicedependent import models
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
try:
@@ -16,54 +16,72 @@ try:
except:
stdout = sys.stdout
def hex_format(data):
return ' '.join('{:02X}'.format(byte) for byte in data)
def multiline_hex(data, bpl):
""" data: bytes, bpl: int (bytes to be displayed per line) """
data = hex_format(data).split()
data = [' '.join(data[i:i+bpl]) for i in range(0, len(data), bpl)]
return '\n'.join(data) + '\n'
def main():
parser = argparse.ArgumentParser()
parser.add_argument('image')
parser.add_argument('outfile', nargs='?', type=argparse.FileType('wb'), default=stdout)
parser.add_argument('--model', default='QL-500')
parser.add_argument('--list-models', action='store_true', \
help='List available models and quit (the image argument is still required but ignored)')
parser.add_argument('--threshold', type=int, default=170)
parser.add_argument('--loglevel', type=lambda x: getattr(logging, x), default=logging.WARNING)
parser.add_argument('image', help='The image file to create a label from.')
parser.add_argument('outfile', nargs='?', type=argparse.FileType('wb'), default=stdout, help='The file to write the instructions to. Defaults to stdout.')
parser.add_argument('--model', '-m', default='QL-500', help='The printer model to use. Check available ones with `brother_ql_info --list-models`.')
parser.add_argument('--label-size', '-s', default='62', help='The label size (and kind) to use. Check available ones with `brother_ql_info --list-label-sizes`.')
parser.add_argument('--threshold', '-t', type=float, default=70.0, help='The threshold value (in percent) to discriminate between black and white pixels.')
parser.add_argument('--loglevel', type=lambda x: getattr(logging, x), default=logging.WARNING, help='Set to DEBUG for verbose debugging output to stderr.')
args = parser.parse_args()
logging.basicConfig(level=args.loglevel)
logging.getLogger("PIL.PngImagePlugin").setLevel(logging.WARNING)
args.model = args.model.upper()
if args.list_models:
print('Supported models:')
print('\n'.join(models))
sys.exit(0)
try:
qlr = BrotherQLRaster(args.model)
except BrotherQLUnknownModel:
sys.exit("Unknown model. Use option --list-models to show available models.")
sys.exit("Unknown model. Use the command brother_ql_info --list-models to show available models.")
try:
label_type_specs[args.label_size]
except ValueError:
sys.exit("Unknown label_size. Check available sizes with the command brother_ql_info --list-label-sizes")
qlr.exception_on_warning = True
device_pixel_width = qlr.get_pixel_width()
im = Image.open(args.image)
hsize = int(im.size[1] / im.size[0] * device_pixel_width)
im = im.resize((device_pixel_width, hsize), Image.ANTIALIAS)
im = im.convert("L")
arr = np.asarray(im, dtype=np.uint8)
arr.flags.writeable = True
white_idx = arr[:,:] < args.threshold
black_idx = arr[:,:] >= args.threshold
arr[white_idx] = 1
arr[black_idx] = 0
create_label(qlr, args.image, args.label_size, threshold=args.threshold)
args.outfile.write(qlr.data)
def create_label(qlr, image, label_size, threshold=70, **kwargs):
label_specs = label_type_specs[label_size]
if label_specs['kind'] == ENDLESS_LABEL:
device_pixel_width = qlr.get_pixel_width()
im = Image.open(image)
hsize = int(im.size[1] / im.size[0] * device_pixel_width)
im = im.resize((device_pixel_width, hsize), Image.ANTIALIAS)
im = im.convert("L")
arr = np.asarray(im, dtype=np.uint8)
arr.flags.writeable = True
white_idx = arr[:,:] < threshold
black_idx = arr[:,:] >= threshold
arr[white_idx] = 1
arr[black_idx] = 0
elif label_specs['kind'] == DIE_CUT_LABEL:
dots_printable = label_specs['dots_printable']
im = Image.open(image)
im = im.convert("L")
if im.size[0] == dots_printable[1] and im.size[1] == dots_printable[0]:
im = im.rotate(90, expand=True)
if im.size[0] != dots_printable[0] or im.size[1] != dots_printable[1]:
sys.exit("Check your image dimensions. Expecting: " + str(dots_printable))
new_im = Image.new(im.mode, (720, dots_printable[1]), 255)
new_im.paste(im, (720-im.size[0], 0))
im = new_im
arr = np.asarray(im, dtype=np.uint8)
arr.flags.writeable = True
white_idx = arr[:,:] < threshold
black_idx = arr[:,:] >= threshold
arr[white_idx] = 1
arr[black_idx] = 0
else:
raise NotImplementedError("Label kind %s not implemented yet." % label_specs['kind'])
try:
qlr.add_switch_mode()
@@ -76,9 +94,16 @@ def main():
except BrotherQLUnsupportedCmd:
pass
qlr.add_status_information()
qlr.mtype = 0x0A
qlr.mwidth = 62
qlr.mlength = 0
tape_size = label_specs['tape_size']
if label_specs['kind'] in (DIE_CUT_LABEL, ROUND_DIE_CUT_LABEL):
qlr.mtype = 0x0B
qlr.mwidth = tape_size[0]
qlr.mlength = tape_size[1]
else:
qlr.mtype = 0x0A
qlr.mwidth = tape_size[0]
qlr.mlength = 0
qlr.pquality = 1
qlr.add_media_and_quality(im.size[1])
try:
qlr.add_autocut(True)
@@ -91,7 +116,10 @@ def main():
qlr.add_expanded_mode()
except BrotherQLUnsupportedCmd:
pass
qlr.add_margins()
if label_specs['kind'] in (DIE_CUT_LABEL, ROUND_DIE_CUT_LABEL):
qlr.add_margins(dots=0)
else:
qlr.add_margins()
try:
qlr.add_compression(True)
except BrotherQLUnsupportedCmd:
@@ -99,7 +127,5 @@ def main():
qlr.add_raster_data(arr)
qlr.add_print()
args.outfile.write(qlr.data)
if __name__ == "__main__":
main()

View File

@@ -10,7 +10,6 @@ import numpy as np
from .devicedependent import models, \
min_max_feed, \
min_max_length_dots, \
paper_dimensions, \
number_bytes_per_row, \
right_margin_addition, \
compressionsupport, \