mirror of
https://github.com/inventree/inventree-website.git
synced 2025-06-12 01:55:37 +00:00
deploy: 7a9a696007
This commit is contained in:
@ -31,11 +31,11 @@
|
||||
<meta property="og:url" content="/SergeoLacruz/inventree-zebra-plugin" />
|
||||
<meta property="og:site_name" content="InvenTree" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="article:published_time" content="2024-04-22T00:55:04+00:00" />
|
||||
<meta property="article:published_time" content="2024-04-24T21:49:01+00:00" />
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta property="twitter:title" content="Inventree Zebra Plugin" />
|
||||
<script type="application/ld+json">
|
||||
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"SergeoLacruz"},"dateModified":"2024-04-22T00:55:04+00:00","datePublished":"2024-04-22T00:55:04+00:00","description":"Zebra Label Printer Plugin for Inventree","headline":"Inventree Zebra Plugin","mainEntityOfPage":{"@type":"WebPage","@id":"/SergeoLacruz/inventree-zebra-plugin"},"url":"/SergeoLacruz/inventree-zebra-plugin"}</script>
|
||||
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"SergeoLacruz"},"dateModified":"2024-04-24T21:49:01+00:00","datePublished":"2024-04-24T21:49:01+00:00","description":"Zebra Label Printer Plugin for Inventree","headline":"Inventree Zebra Plugin","mainEntityOfPage":{"@type":"WebPage","@id":"/SergeoLacruz/inventree-zebra-plugin"},"url":"/SergeoLacruz/inventree-zebra-plugin"}</script>
|
||||
<!-- End Jekyll SEO tag -->
|
||||
|
||||
</head>
|
||||
@ -69,19 +69,21 @@
|
||||
<p> SergeoLacruz</p>
|
||||
</span>
|
||||
</a></span>
|
||||
<span class="sm:ml-2 text-sm">last modified: 22 Apr 2024</span>
|
||||
<span class="sm:ml-2 text-sm">last modified: 24 Apr 2024</span>
|
||||
</h2>
|
||||
|
||||
<div class="flex-wrap md:flex md:flex-nowrap">
|
||||
<div class="w-full md:w-auto md:mr-4">
|
||||
<p>Zebra Label Printer Plugin for Inventree</p>
|
||||
|
||||
<p>This is a label printing plugin for <a href="https://inventree.org">InvenTree</a>, which provides support for Zebra Label printers .
|
||||
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.</p>
|
||||
<p>This is a label printing plugin for <a href="https://inventree.org">InvenTree</a>, which provides
|
||||
support for Zebra Label printers. 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.</p>
|
||||
|
||||
<p>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.</p>
|
||||
<p>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.</p>
|
||||
|
||||
<p>Error handling is very basic.</p>
|
||||
|
||||
@ -107,12 +109,12 @@ with an IP address. The output can be configured in the InvenTree plugin user in
|
||||
device /dev/usb/lp0. No printer spooler is involved so far.</p>
|
||||
|
||||
<h3 id="threshold">Threshold</h3>
|
||||
<p>The image from pillow comes in greyscale. The plugin converts it ti pure BW because this gives a much
|
||||
<p>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.</p>
|
||||
|
||||
<h3 id="darkness">Darkness</h3>
|
||||
<p>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
|
||||
It is directly converted to a SD command in ZPL. If your black areas tend to blur out reduce the
|
||||
darkness.</p>
|
||||
|
||||
<h3 id="dots-per-mm">Dots per mm</h3>
|
||||
@ -132,8 +134,8 @@ is passed directly to the printer without any checks. So be careful when editing
|
||||
here.</p>
|
||||
|
||||
<h2 id="label-template">Label Template</h2>
|
||||
<p>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:</p>
|
||||
<p>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:</p>
|
||||
|
||||
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> @page {
|
||||
{% localize off %}
|
||||
@ -146,13 +148,32 @@ that defines the label size as shown below:</p>
|
||||
}
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>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.</p>
|
||||
<p>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.</p>
|
||||
|
||||
<h2 id="multi-printer-hack">Multi printer hack</h2>
|
||||
<p>We have the requirement to print labels in different sizes. As we do not
|
||||
want to change the reel for each print we set up a second printer loaded
|
||||
with a different label size. InvenTree is not yet able to handle different
|
||||
printers. So I added a multi printer hack. You can define a key with an IP
|
||||
address in the label meta data:</p>
|
||||
|
||||
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{"ip_address":"xxx.yyy.zzz.eee"}
|
||||
{"darkness":xx}
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>If the printer driver finds that key, the IP address from the printer settings
|
||||
is overwritten with the address from the meta data. So the print will end up
|
||||
in another printer.</p>
|
||||
|
||||
<p>Only the IP address and darkness can be overwritten so far. All other settings remain.</p>
|
||||
|
||||
<h2 id="how-it-works">How it works</h2>
|
||||
<p>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.</p>
|
||||
<p>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.</p>
|
||||
|
||||
<p>The next part is this:</p>
|
||||
|
||||
@ -167,7 +188,7 @@ for the IP connection to the printer.</p>
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>The name of the class can be freely chosen. You reference to it in the entry_points section of the setup.py file.
|
||||
The parameters need to be like in the example. Then there is the description block. The keywords are fixed and
|
||||
The parameters need to be like in the example. Then there is the description block. The keywords are fixed and
|
||||
need to be like that. The values are found in the UI as shown in the pictures below.</p>
|
||||
|
||||
<p><img src="/assets/plugins/plugin_admin.png" alt="Admin">
|
||||
@ -191,9 +212,9 @@ need to be like that. The values are found in the UI as shown in the pictures be
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>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.
|
||||
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 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.
|
||||
one is the description in the UI.
|
||||
After that we need to define a function:</p>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">print_label</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">){</span>
|
||||
@ -212,27 +233,27 @@ After that we need to define a function:</p>
|
||||
<li>png_file</li>
|
||||
</ul>
|
||||
|
||||
<p>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.
|
||||
<p>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.</p>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">fn</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span> <span class="p">:</span> <span class="mi">255</span> <span class="k">if</span> <span class="n">x</span> <span class="o">></span> <span class="n">Threshold</span> <span class="k">else</span> <span class="mi">0</span>
|
||||
<span class="n">label_image</span> <span class="o">=</span> <span class="n">label_image</span><span class="p">.</span><span class="nf">convert</span><span class="p">(</span><span class="sh">'</span><span class="s">L</span><span class="sh">'</span><span class="p">).</span><span class="nf">point</span><span class="p">(</span><span class="n">fn</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="sh">'</span><span class="s">1</span><span class="sh">'</span><span class="p">)</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>The threshold can by modified by a plugin parameter. 200 is a good starting value. This trick gives much better prints.
|
||||
<p>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 of this directly into the ZPL library.</p>
|
||||
|
||||
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">l</span> <span class="o">=</span> <span class="n">zpl</span><span class="p">.</span><span class="nc">Label</span><span class="p">(</span><span class="n">Height</span><span class="p">,</span> <span class="n">Width</span><span class="p">,</span> <span class="n">dpmm</span><span class="p">)</span>
|
||||
<span class="n">l</span><span class="p">.</span><span class="nf">origin</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
|
||||
<span class="n">li</span><span class="p">.</span><span class="nf">set_darkness</span><span class="p">(</span><span class="n">darkness</span><span class="p">)</span>
|
||||
<span class="bp">...</span>
|
||||
<span class="n">l</span><span class="p">.</span><span class="nf">write_graphic</span><span class="p">(</span><span class="n">label_image</span><span class="p">,</span> <span class="n">Width</span><span class="p">)</span>
|
||||
<span class="n">l</span><span class="p">.</span><span class="nf">endorigin</span><span class="p">()</span>
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>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.
|
||||
The third parameter is the resolution of the printer in dots per mm.
|
||||
write_graphic converts the pillow data to ZPL.</p>
|
||||
|
||||
<p>The plugin was tested with a labels of various sizes defined using css and html. The DPI scaling
|
||||
@ -248,11 +269,11 @@ Let’s have a look at the following printout:</p>
|
||||
|
||||
<p><img src="/assets/plugins/qr.png" alt="QRCodes"></p>
|
||||
|
||||
<p>Both codes have been printed with the same printer on the same reel. The left one is
|
||||
<p>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.</p>
|
||||
|
||||
<h3 id="secret-1-scale">Secret 1, Scale</h3>
|
||||
<p>The printer resolution is 8 dots per mm resulting in a dot size of 0.125mm. The QR code pixel
|
||||
<p>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.</p>
|
||||
|
||||
@ -260,7 +281,7 @@ pixels plus one in the frame, so 23 pixel. The frame is set in the HTML descript
|
||||
</code></pre></div></div>
|
||||
|
||||
<p>I selected two dots per pixel. So 23 * 2 * 0.125 = 6.125mm. If the size is something different
|
||||
scaling takes place and the result might be worse. If you like a larger printout select more
|
||||
scaling takes place and the result might be worse. If you like a larger printout select more
|
||||
dots per pixel. From a certain size upwards the value does not matter any more because the code
|
||||
gets large enough to be readable in any quality.</p>
|
||||
|
||||
@ -273,9 +294,9 @@ media type and printer age. The printer head tends to wear out and the darkness
|
||||
need an adjustment from time to time.</p>
|
||||
|
||||
<h3 id="alternative">Alternative</h3>
|
||||
<p>You can also bypass the InvenTree template and printing system and directly create ZPL from
|
||||
<p>You can also bypass the InvenTree template and printing system and directly create ZPL from
|
||||
the parts data. The printer knows best how to render the label and the print quality is best.
|
||||
If you are interested in this way have a look at the <a href="https://github.com/yellowcrescent/inventree-zpl-plugin">inventree-zpl-plugin</a>
|
||||
If you are interested in this way have a look at the <a href="https://github.com/yellowcrescent/inventree-zpl-plugin">inventree-zpl-plugin</a>
|
||||
that does exactly that.</p>
|
||||
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user