From 3c850251de8663dba1500eeeac7bfa26b3c7bac6 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 19 Feb 2024 22:03:46 +0100 Subject: [PATCH] Update docu in Zebra label printer (#190) * Update docu in Zebra label printer * escape templates --------- Co-authored-by: Matthias Mair --- _repo/inventree-zebra-plugin.md | 132 +++++++++++++++++++++++++------- assets/plugins/qr.png | Bin 0 -> 49321 bytes 2 files changed, 103 insertions(+), 29 deletions(-) create mode 100644 assets/plugins/qr.png diff --git a/_repo/inventree-zebra-plugin.md b/_repo/inventree-zebra-plugin.md index 49efdf39..04b8def2 100644 --- a/_repo/inventree-zebra-plugin.md +++ b/_repo/inventree-zebra-plugin.md @@ -5,7 +5,7 @@ license: MIT open_source: true stable: true maintained: true -pypi: false +pypi: true package_name: github: https://github.com/SergeoLacruz/inventree-zebra-plugin gitlab: @@ -18,21 +18,20 @@ tags: Label Printer Zebra ZPL Zebra Label Printer Plugin for Inventree This is a label printing plugin for [InvenTree](https://inventree.org), which provides support for Zebra Label printers . -It supports printing to just GK420T with one label size (50x30) so far. So it is very simple. It uses the zpl library to -convert the png data provided by InvenTree to Zebras bitmap format. +It was only tested with GK420T but should work for other ZPL printers too. It uses the ZPL library to +convert the png data provided by InvenTree to Zebra's bitmap format. It can output the print data either to a local printer connected to the computer via USB or to a network printer -with an IP address. The output can be configured in the InvenTree plugin user interface. So the source code is -a good example for this. +with an IP address. The output can be configured in the InvenTree plugin user interface. Error handling is very basic. ## Installation -Install this plugin using pip with the following command:: +The plugin is on pypi. Install this plugin using pip with the following command: ``` -pip install git+https://github.com/SergeoLacruz/inventree-zebra-plugin +pip install inventree-zebra-plugin ``` ## Configuration Options @@ -47,11 +46,55 @@ In case you use an IP printer set the port number here. The default port number ### Local Device In case of a local printer set the device here. The plugin actually puts the data directly to the -device libe /dev/usb/lp0. No printer spooler is involved so far. +device /dev/usb/lp0. No printer spooler is involved so far. + +### Threshold +The image from pillow comes in greyscale. The plugin converts it ti pure BW because this gives a much +better print result. The threshold between black and white can be adjusted here. + +### Darkness +This is a value that influences the darkness of the print. Allowed values are 0 (white) to 30 (black). +It is directly converted to a SD command in ZPL. If your black areas tend to blur out reduce the +darkness. + +### Dots per mm +This sets the resolution of the printer. You can choose between 8, 12 and 24 +dpmm depending on your printer model. + +### Printer init +This string added to the printer output. It can be used to set special commands +e.g. label rotation, mirror or white on black. Please refer to the ZPL manual +for more information. + +Zebra printers store settings after printing. So if a rotated label has been +printed all following label will be rotated unless you change it. The default +sets the printer to settings that have been useful for me. You might want to +change it according to your requirements. Please keep in mind that this string +is passed directly to the printer without any checks. So be careful when editing +here. + +## Label Template +The label needs a template described in html and css. The template should start with a page definition +that defines the label size as shown below: + +``` + @page { + {% raw %}{% localize off %}{% endraw %} + height: {{ height }}mm; + width: {{ width }}mm; + {% raw %}{% endlocalize %}{% endraw %} + padding: 0mm; + margin: 0px 0px 0px 0px; + background-color: white; + } +``` + +The height and width parameters are defined in the InvenTree admin panel in the label section. These values +have to fit the label size that is in the printer. See the example templates for details on template definition. ## How it works -First import all the stuff you need. Here we use the translation mechanism from django for multi language support. -The import the InvenTree libs and everything you need for plugin. Here we have zpl for the Zebra bitmaps and socket +First import all the stuff you need. Here we use the translation mechanism from Django for multi language support. +The import the InvenTree libs and everything you need for plugin. Here we have ZPL for the Zebra bitmaps and socket for the IP connection to the printer. The next part is this: @@ -95,7 +138,7 @@ SETTINGS = { We need to define a dict with the name SETTINGS. Please be aware the keys need to be in all CAPITAL letters like CONNECTION. Simple parameters are just text strings like the port. We can set a default. The name and description shows up in the UI. -Instead of ta simple test we can also use choices. The first string like "local" it the key you use in the code. The second +Instead of a simple text we can also use choices. The first string like "local" it the key you use in the code. The second one is the description in the UI. After that we need to define a function: @@ -109,10 +152,13 @@ The kwargs is a dict with the following keys: - user - filename - label_instance +- item_instance - width - height - png_file +The item_instance is the part to be printed. This allows direct access to all part data. The arguments width and height +come from the settings of the label in the admin interface. NOT from the html template. For the Zebra printer we use the png_file. This is a PIL (python Pillow) object with the graphic of the label in PNG format. The PIL object is a greyscale image. Because the printer can just print pure BW we convert this to a BW picture. @@ -122,32 +168,60 @@ label_image = label_image.convert('L').point(fn, mode='1') ``` The threshold can by modified by a plugin parameter. 200 is a good starting value. This trick gives much better prints. -We can put the result this directly into the zpl library. +We can put the result of this directly into the ZPL library. ```python -l = zpl.Label(50,30,8) +l = zpl.Label(Height, Width, dpmm) l.origin(0, 0) -l.write_graphic(label_image, 50) +... +l.write_graphic(label_image, Width) l.endorigin() ``` -50,30 is the size of the label in millimeters. The third parameter is the resolution of the printer in -dots per mm. As the Zebra printer has 200dpi we put an eight here. write_graphic converts the pillow data -to zpl. 50 is the with of the image in mm. +Width and Height define is the size of the label in millimeters as described above. +The third parameter is the resolution of the printer in dots per mm. +write_graphic converts the pillow data to ZPL. -The plugin was tested with a label of 50x30 mm defined using css and html in InvenTree as shown below. The DPI scaling -can be chosen in the InvenTree settings. 400 is a good value because it is just double of the printers -resolution. If you save the pillow data to a png file you get a size of 788x473 which fits well to that data. +The plugin was tested with a labels of various sizes defined using css and html. The DPI scaling +can be chosen in the InvenTree settings. 800 is a good value because it gives high quality. + +The rest of the code is just output to the printer on different interfaces. + +## Quality matters +The InvenTree printer system uses a graphical representation of the label. The label is described +in HTML, converted to a pixel graphic and printed. The advantage is independency from printer +models and systems. Disadvantage is larger data and quality problems with darkness and scaling. +Let's have a look at the following printout: + +![QRCodes](/assets/plugins/qr.png) + +Both codes have been printed with the same printer on the same reel. The left one is +hardly readable using my mobile. The right one reads easily even as it is smaller. + +### Secret 1, Scale +The printer resolution is 8 dots per mm resulting in a dot size of 0.125mm. The QR code pixel +and the printer pixel size should be integrally divisible. The code in the picture has 21 +pixels plus one in the frame, so 23 pixel. The frame is set in the HTML description. ``` -