Closed BrianTV98 closed 1 year ago
That is a problem of the printing speed of the printer is very low, so that it works in that printer must lower the quality of the image so that the printer can print the logo, in line 340 of the sample project there is an example code how you can reduce the quality of the image, by default is disabled.
if (Platform.isIOS) {
// Resizes the image to half its original size and reduces the quality to 80%
final resizedImage = img.copyResize(image!, width: image.width ~/ 1.3, height: image.height ~/ 1.3, interpolation: img.Interpolation.nearest);
final bytesimg = Uint8List.fromList(img.encodeJpg(resizedImage));
//image = img.decodeImage(bytesimg);
}
You can change that code to
if (Platform.isIOS || Platform.isAndroid) {
// Resizes the image to half its original size and reduces the quality to 80%
final resizedImage = img.copyResize(image!, width: image.width ~/ 1.3, height: image.height ~/ 1.3, interpolation: img.Interpolation.nearest);
final bytesimg = Uint8List.fromList(img.encodeJpg(resizedImage));
image = img.decodeImage(bytesimg);
}
This will lower the quality of the logo so that the printer is able to print the logo before moving on to the next line.
Thanks for the very quick response. However, reducing the size of the image is unacceptable. That is not true to the printer's original desire to print invoices.
I tried to find another solution. The first step was successful. However, this is only a temporary solution. I would like to share here the direction of reasoning and solution.
To prove it. I cut an image into equal parts with a height of 276. Then I printed the images one at a time. After each writeData I delayed 750 ms. (Can only be done with images with with >= 567).
It finally worked.
And here is the sample code.
static Future<bool> printImage(Image image, String printAddress)async{
image = copyResize(image, width: 567, interpolation: Interpolation.cubic);
int offset = 0;
int pieceCount = (image.height~/ 276).ceil();
bool isSuccess = true;
if(Platform.isAndroid){
final profile = await CapabilityProfile.load();
final generator = Generator(PaperSize.mm80, profile);
List<int> bytes = [];
bytes += generator.image(
image,
isDoubleDensity: false,
align: PosAlign.left
);
bool connectionStatus = await PrintBluetoothThermal.connectionStatus;
if (!connectionStatus) await PrintBluetoothThermal.connect(macPrinterAddress: printAddress);
var result = await PrintBluetoothThermal.writeBytes(bytes);
return result ;
}
for(int i =1; i<=pieceCount; i++){
var tmp = copyCrop(image,x: 0, y: offset, width: image.width, height: 276);
offset += 276;
List<int> bytes = [];
// Using default profile
final profile = await CapabilityProfile.load();
final generator = Generator(PaperSize.mm80, profile);
bytes += generator.image(
tmp,
isDoubleDensity: false,
align: PosAlign.left
);
bool connectionStatus = await PrintBluetoothThermal.connectionStatus;
if (!connectionStatus) await PrintBluetoothThermal.connect(macPrinterAddress: printAddress);
var result = await PrintBluetoothThermal.writeBytes(bytes);
if(!result) isSuccess = false;
await Future.delayed(const Duration(milliseconds: 750));
}
return isSuccess;
}
This idea only works on ios. As for Android, everything works fine. We cannot apply this method to Android because after each photo printing. it will automatically insert feed(1) right after. So we separated it into 2 independent cases for Android and iOS
We tried a few other methods to solve the problem after performing step 1. For example: Increase chunk of ios from 150 -> 200. It worked, however the printer prints photos very slowly after doing this.
Thank you for sharing your experience
I downloaded the sample project and printed it with the XT 423(DOA) bluetooth printer. For text printing and barcode printing works well. However, in the case of printing photos, there is an error. When debugging, I discovered that for every line (pice) cut from the image, the library automatically inserts a blank line. How to fix this?