brother_ql_create: enable creation of die-cut labels
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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, \
|
||||
|
||||
Reference in New Issue
Block a user