【问题标题】:Writing a bitmap to Epson TM88IV through ESC/P commands (Write To NVRam) [closed]通过 ESC/P 命令将位图写入 Epson TM88IV(写入 NVRam)[关闭]
【发布时间】:2012-11-22 20:22:33
【问题描述】:

参考链接:

  1. https://lh4.googleusercontent.com/-ceLtiOLVtME/UMBL1yf4RpI/AAAAAAAAAD0/itid5KibW_I/s1015/Doc1.png

  2. https://lh6.googleusercontent.com/-nrphBDA6sjk/UMA_Ukh7ZSI/AAAAAAAAADY/LwjkgobOaBg/s846/MappingTable.png

更新

我现在使用 LockBits 更改了图像转换,但失败了。谁能给我一些建议?

    /// <summary>
    /// Orginal command Format in Decimal:
    /// 29[GS], 40[(], 76[L], pL, PH, 48(m), 67[fn], 48[a], kc1, kc2, b, xL, xH, yL, yH, c, [d1 -- dk]
    /// pL = Lower bit of sum of parameters (m to dk) = 11(m to c) + last bit of image
    /// pH = Higher bit of sum of parameters (m to dk) = 11(m to c) + last bit of image
    /// kc = Key Code of NVRam, kc1 = first bit of key code, kc2 = second bit of key code. P.S.: The key code will be hardcode H1.
    /// b = number of colors = 1
    /// xL & xH = Lower bit of image width, e.g. Width = 128 = 0x0080 then xL = 0x80, xH = 0x00
    /// </summary>
    /// <param name="pLogo"></param>
    public void LoadImageToPrinter(Bitmap pLogo)
    {
        BitmapData oBmpData = pLogo.LockBits(new Rectangle(0, 0, pLogo.Width, pLogo.Height), ImageLockMode.ReadOnly, pLogo.PixelFormat);

        //The list contains all the commands in Decimal format
        List<int> oCommandList = new List<int>();

        //k = (int((xL + xH × 256) + 7)/8) × (yL + yH × 256)

        string HexValueOfX = pLogo.Width.ToString("X4");
        string HexValueOfY = pLogo.Height.ToString("X4");

        //k
        int oExpectedImageByteCount = Math.Abs(oBmpData.Stride) * pLogo.Height;

        //Total bit used for parameters
        int oTotalParameterBitCount = 11 + oExpectedImageByteCount;

        //The hex value for the oTotalParameterBitCount
        string oTotalParameterBitCountInHex = oTotalParameterBitCount.ToString("X4").PadLeft(4, '0');

        //GS, (, L
        oCommandList.AddRange(new int[] { 29, 40, 76 });

        //pL
        oCommandList.Add(GetLowerHexValue(oTotalParameterBitCountInHex));

        //pH
        oCommandList.Add(GetHigherHexValue(oTotalParameterBitCountInHex));

        //m,  fn, a,  kc1, kc2, b
        oCommandList.AddRange(new int[] { 48, 67, 48, (int)'H', (int)'1', 1 });

        //xL, xH
        oCommandList.AddRange(new int[] { GetLowerHexValue(HexValueOfX), GetHigherHexValue(HexValueOfX) });

        //yL, yH, c
        oCommandList.AddRange(new int[] { GetLowerHexValue(HexValueOfY), GetHigherHexValue(HexValueOfY), 49 });

        //Append the image bit to the List
        byte[] oImageByte = new byte[oExpectedImageByteCount];
        IntPtr oPtr = oBmpData.Scan0;
        Marshal.Copy(oPtr, oImageByte, 0, oExpectedImageByteCount);
        pLogo.UnlockBits(oBmpData);

        //Clear NVRam
        mThermalPrinterLibrary.Write(new int[] { 29, 40, 76, 5, 0, 48, 65, 67, 76, 82 }.IntArrayToCharString());

        //Store graphics data
        mThermalPrinterLibrary.Write(oCommandList.ToArray().IntArrayToCharString());
        mThermalPrinterLibrary.Write(oImageByte);

        //Print the graphics data
        mThermalPrinterLibrary.Write(new int[] { 29, 40, 76, 6, 0, 48, 69, (int)'H', (int)'1', 1, 1 }.IntArrayToCharString());        
}

【问题讨论】:

  • 您似乎在为每个像素添加一个字节:这是错误的;每个字节代表 8 个像素。您还命名了一个变量“oExpectedImageBitCount”。 'oExpectedImageByteCount' 会更好。
  • 更新了变量名,但我仍然不知道如何以正确的方式将位图转换为字节数组,对不起。之前没有任何图像处理经验,我应该在谷歌或其他地方寻找什么?谢谢
  • 这不是特定于图像处理的,只是位操作。您似乎有获取像素的代码(pLogo.GetPixel)。输出的每个字节代表 8 个像素:0x80 是第一个,0x40 是第二个,... 0x01 是第八个。您只需要一次处理 8 个像素并适当设置位的代码,例如使用位移运算符 (
  • 您能向我解释一下第二个参考链接的表格吗?谢谢
  • 两个链接似乎都坏了:-(

标签: c# .net printing command epson


【解决方案1】:

多年前我在 C 中做过这个。我手头没有代码,但它不仅仅是一个 sn-p。为此,您需要执行以下操作。

  • 了解BMP file format - 假设您正在从文件中读取位图。

  • 查看 WINGDI.H (Microsoft Windows SDK),它具有文件头等的 C 样式定义:BITMAPFILEHEADER、BITMAPCOREHEADER、BITMAPINFOHEADER。

  • 处理标题以确定位图是否满足您的要求(例如,为了简化您的处理,您可能希望坚持位图正好是 128 x 98(BITMAPINFOHEADER.biWidth、BITMAPINFOHEADER.biHeight),一个平面 (BITMAPINFOHEADER.biPlanes = 1),是单色的 (BITMAPINFOHEADER.biBitCount =1),未压缩 (BITMAPINFOHEADER.biCompression = 0)。这些限制不是绝对必要的,但会简化您的处理。

  • 处理像素数组,并将其转换为 ESCPOS 转义序列所需的格式。

或者,您可能想放弃使用 ESCPOS,而使用 OPOS / UPOS / POS for .NET,它提供了用于访问 POS 外围设备的更高级别的 API:POSPrinter 设备exposes a method to print a bitmap,并避免您需要做格式转换自己。您需要下载Epson OPOS ADK 来执行此操作。 祝你好运!

更新

而且来自 EPSON 的文件简直就是地狱,不明白它需要什么。

the document from Epson 有什么困难?也许您可以尝试针对您不了解的部分提出具体问题。

更新 2

这里有一些提示:

  • GS ( L pL pH m fn [params] : pL 和 pH 是指定长度的 16 位整数值的低位和高位字节以下数据(即m fn [params])。

  • 对于 fn = 67(定义 NV 数据栅格格式),格式为 GS ( L pL pH m fn a kc1 kc2 b xL xH yL yH [c d1...dk]1.. .[c d1...dk]b 其中 m = 48,fn = 67,a = 48。

  • kc1 和 kc2 是用于在打印时识别下载数据的键码

  • b 指定下载数据的颜色数,1 为单色,2 为双色。

  • xL 和 xH 是 16 位整数值的低位和高位字节,用于定义图像的点(像素)宽度。

  • yL 和 yH 是 16 位整数值的低位和高位字节,用于定义图像的点(像素)高度。

  • 对于单色位图,将有一个块 c d1 ... dk 指定颜色 c 和像素数据。对于彩色位图,每种颜色有一个块 c d1 ... dk

  • 像素数据 d1 ... dkk 个字节,其中 k = (width x (height+7))/8。位设置为 1 表示打印该点(像素)。

我不知道上面的内容是否比爱普生文档中的注释更清楚;如果不说你不明白的地方。

更新 3

这是一个基于 128 宽 x 98 高位图的示例,如您的问题所示,为简单起见,单色。

  • 您需要 k = (int(width + 7)/8) × (height) = (int(128+7)/8) x 98 = 16 x 98 = 1568 字节的像素数据 ( bit = 1 表示点打印):d1 to d1568

  • 假设颜色 c = 颜色 1 = 49 十进制 = 0x31 十六进制(也可以是 0x32 或 0x33)

  • 宽度 = 128 = 0x0080,所以 xH = 0x00,xL = 0x80

  • 高度 = 98 = 0x0062,所以 yH = 0x00,yL = 0x62

  • b = 颜色数 = 1

  • 假设您的密钥是“H1”,即 kc1 = 'H' = 0x48 和 kc2 = '1' = 0x31

  • 参数长度 = m fn a kc1 kc2 b xL xH yL yH cd1 ... d1568 的长度 = 11 + 1568 = 1579 = 0x062B 十六进制,所以 pL = 0x2B,pH = 0x06。

所以你发送的数据将是:

GS ( L pL pH m fn a kc1 kc2 b xL xH yL yH c d1...d1568

十六进制:

1D 28 4C 2B 06 30 43 30 48 31 01 80 00 62 00 31 d1 ... d1568

【讨论】:

  • 感谢您的回复,我曾尝试使用 POS.Net(OPOS),但我发现该库不像 ESC/P 那样稳定。(太长无法分辨)而来自 EPSON 的文档只是像地狱一样,不明白它需要什么。无论如何,谢谢。
  • 感谢您的解释和耐心,但我只理解第 2 点和第 3 点。也许我应该找到另一种存储位图的方法,例如使用爱普生的一些实用程序 :( 无论如何,谢谢您的回复
  • 非常感谢!!我将尝试用 C# 编写一些代码并尝试发送到打印机。并会在这里发布,谢谢!!!
  • @Joe 如何获得 d1...d1568 格式?你循环通过图像高度和图像宽度然后获取像素数据?使用它作为我的 c# 代码的基础,但它打印出乱码。
猜你喜欢
  • 1970-01-01
  • 2012-07-24
  • 1970-01-01
  • 2014-09-24
  • 2017-06-09
  • 1970-01-01
  • 1970-01-01
  • 2012-01-06
  • 1970-01-01
相关资源
最近更新 更多