将 PNG 图像转换为 ZPL 代码

Posted

技术标签:

【中文标题】将 PNG 图像转换为 ZPL 代码【英文标题】:Converting PNG image to ZPL code 【发布时间】:2018-09-22 18:00:42 【问题描述】:

我需要使用 ZPL 打印机将 PNG 图像打印到标签上。这个想法是将PNG图像转换为单色图像,然后使用图像数据生成必要的ZPL代码以打印图像。

经过一些谷歌搜索和编码后,我有一段代码可以做到这一点。生成的 ZPL 代码在标签 (http://labelary.com) 上似乎很好。

生成 ZPL 代码的代码大多取自这里 --> How to optimize ASCII HEX for BMP to ZPL as using in Labelary

不幸的是,当尝试使用生成的 ZPL 代码打印标签时,结果如下: Not supposed to look like this

图像应如下所示: ImageToConvert

我使用的代码是这样的:

static void Main(string[] args)
    

        // 1. Convert Image to monochrome bmp
        string bitmapFilePath = @"somepath.bmp";
        Bitmap imageToConvert = new Bitmap(bitmapFilePath);
        var rectangle = new Rectangle(0, 0, imageToConvert.Width, imageToConvert.Height);
        Bitmap monochromeImage = imageToConvert.Clone(rectangle, PixelFormat.Format1bppIndexed);

        // Mirror image
        monochromeImage.RotateFlip(RotateFlipType.Rotate180FlipX);

        // Save mono image            
        monochromeImage.Save("somePathMono.bmp", ImageFormat.Bmp);

        // 2. Convert to ZPL
        ConvertImage();   

    

    public static void ConvertImage()
    
        string bitmapFilePath = "somePathMono.bmp";
        int w, h;
        Bitmap b = new Bitmap(bitmapFilePath);
        w = b.Width; h = b.Height;
        byte[] bitmapFileData = System.IO.File.ReadAllBytes(bitmapFilePath);
        int fileSize = bitmapFileData.Length;

        int bitmapDataOffset = int.Parse(bitmapFileData[10].ToString()); ;
        int width = w; // int.Parse(bitmapFileData[18].ToString()); ;
        int height = h; // int.Parse(bitmapFileData[22].ToString()); ;
        int bitsPerPixel = int.Parse(bitmapFileData[28].ToString()); 
        int bitmapDataLength = bitmapFileData.Length - bitmapDataOffset;
        double widthInBytes = Math.Ceiling(width / 8.0);

        while (widthInBytes % 4 != 0)
        
            widthInBytes++;
        

        // Copy over the actual bitmap data without header data            
        byte[] bitmap = new byte[bitmapDataLength];

        Buffer.BlockCopy(bitmapFileData, bitmapDataOffset, bitmap, 0, bitmapDataLength);           

        // Invert bitmap colors
        for (int i = 0; i < bitmapDataLength; i++)
        
            bitmap[i] ^= 0xFF;
                     

        // Create ASCII ZPL string of hexadecimal bitmap data
        string ZPLImageDataString = BitConverter.ToString(bitmap);            
        ZPLImageDataString = ZPLImageDataString.Replace("-", string.Empty);

        // Add new line every 1023 chars characters
        string ZPLImageDataStringWithNewLine = SpliceText(ZPLImageDataString, 1023);            

        // Create ZPL command to print image
        string ZPLCommand = string.Empty;

        ZPLCommand += "^XA";
        ZPLCommand += "^FO20,20";
        ZPLCommand +=
        "^GFA," +
        bitmapDataLength.ToString() + "," +
        bitmapDataLength.ToString() + "," +
        widthInBytes.ToString() + "," +
        System.Environment.NewLine +
        ZPLImageDataStringWithNewLine;

        ZPLCommand += "^XZ";

        System.IO.StreamWriter sr = new System.IO.StreamWriter("zplCodePath", false, System.Text.Encoding.Default);

        sr.Write(ZPLCommand);
        sr.Close();       
    

    public static string SpliceText(string text, int lineLength)
    
        return Regex.Replace(text, "(." + lineLength + ")", "$1" + Environment.NewLine);
    

我们使用 Zebra ZT 410 打印机

有人可以帮我找出问题所在吗?在这一点上我没有想法。

谢谢!

更新:似乎问题在于我在图像数据中的每个 x 字符之后放置的换行符。我不明白为什么。我的代码非常适用于较小的图像(我不必添加新行),但是对于具有长图像数据字符串的大图像,如果我不添加新行,它就不会打印。

任何帮助将不胜感激!

【问题讨论】:

我很困惑,看起来您的图像是一个带有条形码的 R?为什么不直接用文本绘制和 R 并在 zpl 中正确定位条形码代码? 这是示例图像,还是您想要在所有标签上显示的图像?直接在 ZPL 中生成大 R 和条形码可能会更容易。 另外,我很确定如果你只是想走图像路线,为什么不只对图像进行 base64 编码并使用它呢?这就是我们对所有图像所做的事情,而且效果很好。 提供的图片只是样张图片,实物比较复杂,而且每次都在变化,所以无法重新制作 @samMarion 您的意思是将图像的字节数组编码为 Base64 吗?也许你有一个例子? 【参考方案1】:

因为我在 ZPL 指南和提供不同解决方案的各种参考资料中遇到了这样的问题(似乎从未完全适用于我的用例),所以我创建了一个简单的 .net core application,它采用标签图像并将其转换为 ZPL,要么到文件(如果提供了输出)或直接到控制台,以便在 bash 脚本中通过管道传输。

【讨论】:

感谢您的出色图书馆。就我而言,我有“索引超出边界数组”错误,我编辑 ConvertBitmapToHex 方法,使用 List 而不是 byte[] 固定问题。 @HamidrezaShokouhi 很高兴让我知道,我会调查这个问题并为此创建一个错误修复。【参考方案2】:

我遇到了同样的问题,使用 online tool 将您的 png/jpeg 转换为 ZPL 单色格式以进行打印并在 viewer 上验证您的 ZPL 代码

【讨论】:

以上是关于将 PNG 图像转换为 ZPL 代码的主要内容,如果未能解决你的问题,请参考以下文章

如何从标签 api 响应(javascript)中检索 png

如何将 html 地图转换为图像(png 或 jpg )

将大型光栅图形图像(位图、PNG、JPEG 等)转换为非矢量 postscript

使用 NodeJS 将 OpenType / TrueType 格式转换为 png 图像

将 .mbtiles 转换为 .png 图像

如何使用 OpenCV C++ 将 24 位深度的 PNG 图像转换为 8 位深度的 PNG 图像