使用带 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
数组。
我有此代码,使用 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
数组。