使用带 Firemonkey 的蓝牙热敏打印机打印位图 Android

Printing Bitmap Using Bluetooth Thermal Printer With Firemonkey Android

我有此代码,使用 android 使用 firemonkey delphi,使用蓝牙热敏打印机打印文本成功, 我的朋友为打印位图进行了修改,但是与过程 bitmaptostr 的任何错误访问冲突。

procedure TBluetoothPrinter.Send(Data: TArray<Byte>);
begin
  if Data = nil then
    Exit; // nothing to write

  Check(OutputStream <> nil, 'Cannot retrieve output stream');
  OutputStream.write(ToJavaByteArray(Data));
end;

procedure Printing(sText: string);
begin
  with TBluetoothPrinter.Create do
  begin
    Send(TEncoding.ANSI.GetBytes(sText + CRLF));
  end;
end;

function BitmapToStr(BMP: TBitmap; EscapeStr:String; SliceEscapeStr:String; BitsSlice: Byte = 8):String;
var
  BMPData: TBitmapData;
  AColor: TAlphaColor;

  nCol, nRow, nIndex: integer;
  nOffset, nBytePos, nBitPos: integer;
  nSliceIndex, nLum: integer;
  nSlice, nBit, nTmpBit, BytesSlice: byte;
  ADots: Array of boolean;
  sSlice: String;
begin
  try
    SetLength(ADots, (BMP.Height * BMP.Width));
    nIndex := 0;

    for nRow := 0 to BMP.Height-1 do
    begin
      for nCol := 0 to BMP.Width-1 do
      begin
        AColor := BMPData.GetPixel(nCol, nRow);
        nLum := Trunc((TAlphaColorRec(AColor).R * 0.3)  + (TAlphaColorRec(AColor).G * 0.59) + (TAlphaColorRec(AColor).B * 0.11));
        ADots[nIndex] := (nLum < 127);
        inc(nIndex);
      end;
    end;

   BytesSlice := (BitsSlice div 8);

    if BitsSlice mod 8 > 0 then
      inc(BytesSlice);

    Result := EscapeStr;
    nOffset := 0;
    while (nOffset < BMP.Height) do
    begin
      Result := Result + SliceEscapeStr;

      for nCol := 0 to BMP.Width-1 do
      begin
        for nSliceIndex := 0 to BytesSlice - 1 do
        begin
          nSlice := 0;
          for nBit := 0 to 7 do
          begin
            nBytePos := (((nOffset div 8) + nSliceIndex) * 8) + nBit;
            nBitPos := (nBytePos * BMP.Width) + nCol;

            nTmpBit := 0;
            if (nBitPos < Length(ADots)) then
            begin
              if ADots[nBitPos] then
                nTmpBit := 1
              else
                nTmpBit := 0;
            end;
            nSlice := nSlice or (nTmpBit shl (7 - nBit));
          end;

          Result := Result + Chr(nSlice);
        end;
      end;

      inc(nOffset, BitsSlice);
      Result := Result + CRLF;
    end;
  finally
     ADots := nil;
  end;
end;

有人有解决方案或示例参考吗?

您在 BitmapToStr() 中遇到的错误是您从未 Map 使用 BMP 位图的 BMPData

将此添加到函数的开头:

bmp.Map(TMapAccess.Read, BMPData);
try
  ...

最后:

finally
  bmp.Unmap(BMPData);
end;

另一方面,您不需要 try..finally..end 块来确保正确清理 ADots 数组。