androiddelphibluetoothfiremonkeythermal-printer

Printing Bitmap Using Bluetooth Thermal Printer With Firemonkey Android


I have this code is success for printing text with bluetooth thermal printer using android using firemonkey delphi, my friend modified for printing bitmap, but any some error access violation with procedure 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;

anyone have some solution or sample reference?


Solution

  • The error you have in BitmapToStr() is that you never Map the BMPData with the BMP bitmap.

    Add this to the beginning of the function:

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

    and at the end:

    finally
      bmp.Unmap(BMPData);
    end;
    

    On the other hand, you don't need the try..finally..end block to assure proper cleanup of the ADots array.