使用 ESC POS 生成 QRCode 并在热敏打印机中打印 - 紫江 58mm - Delphi 10.2

Generate QRCode and Print in Printer Thermal using ESC POS - ZIJIANG 58mm - Delphi 10.2

我正在尝试在 delphi、android 平台 (firemonkey) 中的热敏 pos 蓝牙打印机上打印二维码。 打印机已连接,可以打印文字,但无法生成和打印二维码,如有帮助,将不胜感激

pos打印机的商标是P08-580LD(紫江)

这是我在 delphi-android 10.2 中使用的代码。

        sock.connect;
         // Reset Printer
         ostream.write(StringToJA(escResetPrinter,'iso8859-2'));

        ostream.write(StringToJA(pO8escBoldOn,'iso8859-2'));
        ostream.write(StringToJA('Naziv 1'+escNewLine    , 'iso8859-2'));
        ostream.write(StringToJA(pO8escBoldOff,'iso8859-2'));

        ostream.write(StringToJA(pO8escFontA,'iso8859-2'));
        ostream.write(StringToJA('Adresa'+escNewLine    , 'iso8859-2'));
        ostream.write(StringToJA(escResetPrinter,'iso8859-2'));

        ostream.write(StringToJA(pO8escFontB,'iso8859-2'));
        ostream.write(StringToJA('MB xxxxx, ID HR-AB-99-0125--54'+escNewLine    , 'iso8859-2'));
        ostream.write(StringToJA(escResetPrinter,'iso8859-2'));

        ostream.write(StringToJA(pO8escUnerlineOn,'iso8859-2'));
        ostream.write(StringToJA('IBAN: xxxxxxxxx'+escNewLine    , 'iso8859-2'));
        ostream.write(StringToJA(pO8escUnerlineOff,'iso8859-2'));

        ostream.write(StringToJA('OIB 99999999'+escNewLine    , 'iso8859-2'));

       // start - qr-code //
        ostream.write(StringToJA(chr(27)+chr(90)+chr(0)+chr(7)+chr(15)+chr(25)+chr(30)+'dada'  ,'iso8859-2'));

        ostream.write(StringToJA(escResetPrinter,'iso8859-2'));

   Sleep(250);
   ostream.flush();
   ostream.close;

这是打印机的文档,它说明了如何构建代码(十进制)。

https://mega.nz/file/fu4zTCSR#UZ53LSty7dUpRyqzvz8li27amG1KvVlLk0slQFhd5Os

我成功生成了如下图的二维码,但是不行。

根据打印机文档,二维码应该是这样生成的

在android studio 找到了一个函数,如何构建二维码,如果有人知道如何把一个函数变成delphi,我将不胜感激。

.....

 byte[] qrcode = PrinterCommand.getBarCommand("Zijiang Electronic Thermal Receipt Printer!", 0, 3, 6);//
 Command.ESC_Align[2] = 0x01;
 SendDataByte(Command.ESC_Align);
 SendDataByte(qrcode);

public static byte[] getBarCommand(String str, int nVersion, int nErrorCorrectionLevel, int nMagnification)

{   
  if(nVersion<0 | nVersion >19 | nErrorCorrectionLevel<0 | nErrorCorrectionLevel > 3
            | nMagnification < 1 | nMagnification > 8){
          return null;
      }
      
     byte[] bCodeData = null;
     try
     {
      bCodeData = str.getBytes("GBK");
       
     }
     catch (UnsupportedEncodingException e)
     {
       e.printStackTrace();
       return null;
     }

     byte[] command = new byte[bCodeData.length + 7];     
     command[0] = 27;
     command[1] = 90;
     command[2] = ((byte)nVersion);
     command[3] = ((byte)nErrorCorrectionLevel);
     command[4] = ((byte)nMagnification);
     command[5] = (byte)(bCodeData.length & 0xff);
     command[6] = (byte)((bCodeData.length & 0xff00) >> 8);
     System.arraycopy(bCodeData, 0, command, 7, bCodeData.length);
     return command;
   }

在那种迷你 POS 打印机上有非常相似的问题。当直接从 Kotlin(Android Studio,原生)打印时,我设法以某种方式部分解释了他们的官方手册,并得出结论 ESC Z 的工作方式略有不同(实际上它对应于您找到的 Java 代码) ...

  1. ESC Z (27 90)
  2. 第一个字节与 table 行(“版本”)相关,如果为 0 则它将“自动选择”
  3. 起初,我认为第二个字节必须是 'M' (77) - 'L'、'Q'、'H' - 没成功?! (实际上它必须是 0、1、2、3,基于错误更正 - 正如您在此处找到并发布的 Java 代码中所建议的那样)
  4. 该字节与二维码大小有关,1-8
  5. 字符串大小的低字节(例如,对于您的“dada”,它将是 4)
  6. 字符串大小的高字节(对于您的“dada”,它将是 0...如果超过 256 个字符,则长度应为 div 256)
  7. 字符串字符

在你的Delphi代码中,我会改变(一步一步,你可以二进制屏蔽长度...):

// start - qr-code //
ps := 'dada'; // your content string... detalji o računu ili štogod...
l1 := length(ps);
y  := l1 div 256;
x  := l1 - y * 256; 
ostream.write(StringToJA(chr(27)+chr(90)+chr(7)+chr(1)+chr(6)+chr(x)+chr(y)+ps  ,'iso8859-2'));

// please not that 7-1-6 is fixed combination - 7 relates to the table from documentation, 1 relates to error correction (use 0 for "smaller" QR with less redundany, or 2 and 3 for larger more complex QR), 6 relates to size of printed code (can be set lower)