将 PNG 图像打印到 Zebra 网络打印机
我正在尝试找到一种将图像打印到斑马的方法,但遇到了很多麻烦。
根据文档:
第一种编码称为 B64,使用 MIME 对数据进行编码 Base64 方案。 Base64 用于对电子邮件附件进行编码...
Base64 将 6 位编码为字节,扩展了 33% 覆盖未封闭的数据。
第二种编码,称为 Z64, 首先使用LZ77算法压缩数据以减小其大小。 (该算法由 PKZIP 使用,并且是 PNG 的组成部分 图形格式。)
然后使用以下格式对压缩数据进行编码 MIME Base64 方案如上所述。
将计算 CRC 遍历 Base64 编码的数据。
但它没有更多信息。
基本上我尝试使用编码
private byte[] GetItemFromPath(string filepath)
{
using (MemoryStream ms = new MemoryStream())
{
using (Image img = Image.FromFile(filepath))
{
img.Save(ms, ImageFormat.Png);
return ms.ToArray();
}
}
}
然后尝试使用类似的内容进行打印:
var initialArray = GetItemFromPath("C:\\RED.png");
string converted = Convert.ToBase64String(b);
PrintThis(string.Format(@"~DYRED.PNG,P,P,{1},0,:B64:
{0}
^XA
^F0200,200^XGRED.PNG,1,1^FS
^XZ", converted .ToString(), initialArray.Length));
从声音来看,B64 或 Z64 都被接受。
我尝试了一些变体,以及一些生成 CRC 和计算“大小”的方法。 但似乎都不起作用,并且将图形下载到打印机总是被中止。
有没有人设法完成这样的事情?或者知道我哪里出错了?
I am trying to find a way of printing images to a zebra and having a lot of trouble.
According to the docs:
The first encoding, known as B64, encodes the data using the MIME
Base64 scheme. Base64 is used to encode e-mail atachedments ...
Base64 encodes six bits to the byte, for an expantion of 33 percent
over the un-enclosed data.
The second encoding, known as Z64,
first compresses the data using the LZ77 algorithm to reduce its size.
(This algorithm is used by the PKZIP and is intergral to the PNG
graphics format.)
The compressed data is then encoded using the
MIME Base64 scheme as described above.
A CRC will be calculated
accross the Base64-encoded data.
But it doesn't have a great deal more info.
Basically I was trying encoding with
private byte[] GetItemFromPath(string filepath)
{
using (MemoryStream ms = new MemoryStream())
{
using (Image img = Image.FromFile(filepath))
{
img.Save(ms, ImageFormat.Png);
return ms.ToArray();
}
}
}
Then trying to print with something like:
var initialArray = GetItemFromPath("C:\\RED.png");
string converted = Convert.ToBase64String(b);
PrintThis(string.Format(@"~DYRED.PNG,P,P,{1},0,:B64:
{0}
^XA
^F0200,200^XGRED.PNG,1,1^FS
^XZ", converted .ToString(), initialArray.Length));
From the sounds of it, either B64 or Z64 are both accepted.
I've tried a few variations, and a couple of methods for generating the CRC and calculating the 'size'.
But none seem to work and the download of the graphics to the printer is always getting aborted.
Has anyone managed to accomplish something like this? Or knows where I am going wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
我得出这个答案的所有功劳都来自LabView 论坛 用户 Raydur。他发布了一个 LabView 解决方案,可以在 LabView 中打开该解决方案来发送图像。我个人没有用我的打印机运行它,我只是用它来找出正确的图像代码,这样我就可以在我的代码中复制它。我错过的最重要的事情是填充我的十六进制代码。例如,1A 就可以,但如果只有 A,则需要在其前面填充 0 才能发送 0A。您发送的 ZPL 中文件的大小也是字节数组的原始大小,而不是数据的最终字符串表示形式。
我浏览了很多很多论坛和 Stackoverflow 帖子试图解决这个问题,因为这看起来是一件很简单的事情。我已经尝试了其他地方发布的每个解决方案,但我真的只想打印 a.PNG,因为我的打印机(Mobile QLN320)的手册内置了对其的支持。它说要么以 Base64 要么以十六进制发送,我尝试了两者均无济于事。对于任何想要执行 Base64 的人,我在一本较旧的手册中发现,您需要手动计算发送的每个数据包的 CRC 代码,因此我选择使用更简单的十六进制路线。所以这是我要工作的代码!
All credit for me coming to this answer was from LabView Forum user Raydur. He posts a LabView solution that can be opened up in LabView to send images down. I personally didn't run it with my printer, I just used it to figure out the correct image code so I could replicate it in my code. The big thing that I was missing was padding my Hexadecimal code. For example, 1A is fine, but if you have just A, you need to pad a 0 in front of it to send 0A. The size of the file in the ZPL you are sending is also the original size of the byte array, not the final string representation of the data.
I've scoured many, many, many forums and Stackoverflow posts trying to figure this out because it seems like such a simple thing to do. I've tried every single solution posted elsewhere but I really wanted to just print a.PNG because the manual for my printer(Mobile QLN320) has support for it built-in. It says to either send it in Base64 or Hexadecimal, and I tried both to no avail. For anyone wanting to do Base64, I found in an older manual that you need to manually calculate CRC codes for each packet you send so I chose to go with the easier Hexadecimal route. So here is the code I got to work!
ZPL II 编程指南 记录了下载图像的
~DG
命令和 GRF 格式(第 124 页)。 第二卷 添加有关可选压缩格式的详细信息(第 52 页)。首先,您必须将图像转换为 1bpp 双层图像,然后将其转换为十六进制编码的字符串。您可以进一步压缩图像以减少传输时间。然后您可以使用
^ID
命令打印图像。虽然
~DY
命令中固有地支持 PNG 图像,但它的文档记录很少,并且似乎不适用于某些型号的打印机。 ZB64 格式基本上没有文档记录,并且尝试从 Zebra 支持获取更多信息均无果。如果您对 ZB64 感兴趣,则可以使用 基于 Java 的 Zebralink SDK(查看ImagePrintDemo.java
和com.zebra.sdk.printer.internal.GraphicsConversionUtilZpl.sendImageToStream
)。获得命令数据后,如果打印机有打印服务器,则可以通过 TCP/IP 发送命令数据,或者可以通过以
RAW
格式写入打印机来发送命令数据。下面的代码将 5 kB PNG 打印为 13 kB 压缩 GRF(60 kB 未压缩):
The ZPL II Programming Guide documents the
~DG
command and GRF format (page 124) to download images. Volume Two adds details on an optional compression format (page 52).First, you have to convert the image to a 1bpp bi-level image, then convert it to a hex-encoded string. You can further compress the image to reduce transmission time. You can then print the image with the
^ID
command.While there is inherent support for PNG images in the
~DY
command, it is poorly documented and does not seem to work on certain models of printers. The ZB64 format is basically not documented, and attempts to get more information from Zebra support have been fruitless. If you have your heart set on ZB64, you can use the Java based Zebralink SDK (look toImagePrintDemo.java
andcom.zebra.sdk.printer.internal.GraphicsConversionUtilZpl.sendImageToStream
).Once you have the command data, it can be sent via TCP/IP if the printer has a print-server, or it can be sent by writing in
RAW
format to the printer.The code below prints a 5 kB PNG as a 13 kB compressed GRF (60 kB uncompressed):
由于某种原因,我无法让 B64 工作,但幸运的是,我能够通过 Google 搜索到使用普通的旧 JavaScript 使 Z64 工作(在 3 天左右的时间里)。
在 ZPL 编程指南的其他地方,您偶然发现了 CISDFCRC16 命令 - 让我们神秘一点,为什么不 - 部分,其中指出:
撇开日本英语不谈,您现在可以查看16 位参数化 CRC 算法目录 (http://reveng.sourceforge.net/crc-catalogue/16.htm) 并查找 XMODEM 然后我开始寻找我需要
的其余代码并偶然发现了以下内容:
(https://github.com/beatgammit/base64-js/ blob/master/lib/b64.js)
(http://www.lammertbies.nl/comm/info/crc-calculation. html) 移植
来自 ANSI C——注意按位与
自 JavaScript 以来,更新函数返回值都是 0xffff
将每个数字视为 32 位有符号整数。
因此,我将文件作为字节数组 (Uint8Array) 读取,将其解析为字符串,使用 LZ77 压缩,将其转回字节数组并使用 base64 对其进行编码,此时我计算 CRC 并将其全部粘贴到我的ZPL ~DT 命令可节省约 40%。美丽的。
不幸的是,我正在开发一个专有的解决方案,所以我无法发布任何代码。
祝你好运!
For some reason I cannot get B64 to work, but luckily I was able to Google my way into making Z64 work (in 3 soul-searching days or so) using plain old JavaScript.
Somewhere else on the ZPL programming Guide you stumble upon the The CISDFCRC16 command--let's be cryptic, why not--section, which states:
Japanglish aside, you can now check out the Catalogue of parametrised CRC algorithms with 16 bits (http://reveng.sourceforge.net/crc-catalogue/16.htm) and look for the XMODEM algorithm, which happens to be
Aha. I then started looking for the rest of the code I needed and stumbled upon the following:
(https://github.com/beatgammit/base64-js/blob/master/lib/b64.js)
(http://www.lammertbies.nl/comm/info/crc-calculation.html) ported
from ANSI C--with the precaution to bitwise-AND
with 0xffff the update function return value since JavaScript
treats every number as a 32-bit signed integer.
So I read the file as a byte array (Uint8Array), parse it as a string, compress it with LZ77, turn that back into a byte array and encode it using base64, at which point I calculate the CRC and paste it all into my ZPL ~DT command for savings of about 40%. Beautiful.
Unfortunately I'm developing a proprietary solution so I cannot post any code.
Good luck!
查看 ZPL 手册后,您需要计算映像的循环冗余校验 (CRC)。下面是一些计算 CRC 的 C 代码 (来源):
您还可以参考维基百科关于 CRC 的页面,因为它还包含其他代码示例。
https://en.wikipedia.org/wiki/Cyclic_redundancy_check
您发送的其他所有内容看起来好的。我会考虑使用 Zebra SDK 之一。我知道 Android 设备会将图像发送到打印机并为您保存。
After looking at the ZPL manual you need to calculate the Cyclic Redundancy Check (CRC) for the image. Here is some C Code that calculates the CRC (source):
You can also refer to Wikipedia's page on CRC, as it contains other code examples as well.
https://en.wikipedia.org/wiki/Cyclic_redundancy_check
Everything else you are sending down looks good. I would look into using one of the Zebra SDKs. I know the Android one will send an image to the printer and save it for you.
在此 GitHub 项目中,您将找到所需的一切。 https://github.com/BinaryKits/BinaryKits.Zpl
还有一个PNG转GRF具有附加数据压缩功能的图像转换器。
In this GitHub project you will find everything you need. https://github.com/BinaryKits/BinaryKits.Zpl
There is also a PNG to GRF image converter with additional data compression available.
虽然这个问题有 C# 标签,但其他几个答案并不是严格意义上的 C#,所以这里是一个使用 Node 8.5+ (javascript)、使用 java 和 Zebra SDK。对于任何也可以使用 SDK 并执行 POST 请求的 .NET 语言,相同的步骤都非常相似。
然后你可以通过 ZPL 打印图像,例如:
使用类似的东西
Although this question has the C# tag, several other answers are not strictly C#, so here is an answer using Node 8.5+ (javascript), using java and the Zebra SDK. The same steps are very similar for any .NET language that can also use the SDK and perform a POST request.
Then you can print the image via ZPL like:
Using something like
我建议使用一些额外的库,以使您的长期实施更容易。
我通过 BinaryKits.Zpl NuGet 包使用以下代码:
func ToPngBytes 具有以下代码:
该系统可能看起来较慢,因为它从图像创建所有十六进制/二进制数据,但在另一部分,它不使用存储/检索图形,如果您像大多数示例那样立即使用相同的 Zpl 代码提供图像,我会觉得很困惑。
I recommend using some extra library to make your implementation easier on the lon term.
I use the following code through the BinaryKits.Zpl NuGet package:
The func ToPngBytes has the following code:
This system may seem slower as it creates all the Hex/Binary data from your image but on the other part, it doesn't use the store/retrieve graphics which I find confusing if you are providing the image right away with the same Zpl code as most of examples do.