Open dishuostec opened 1 year ago
The image is a paletted image, so the interpolation modes aren't correct for that. It would have to be converted to an 32-bit RGBA image first, via final rgbaImage = image.convert(numChannels: 4);
.
V3 didn't support paletted images, so all images were 32-bit RGBA.
Since copyResize always returns a new image, I'll have it auto-convert the image if you use non-nearest interpolation.
I pushed the update to github, to auto convert images for transform functions that use non-nearest interpolation. I'll be doing a publish soon.
If you want to convert it back to a palette image, you can use the quantize or ditherImage functions.
I'm having a similar problem. I have an image in QR Code that I send in bytes to a printer via the serial port, using the package in version 3 it was working but now it comes out all wrong. see photo below.
Future<void> image(Image src) async {
final Image image = Image.from(src); // make a copy
const bool highDensityVertical = true;
invert(image);
flip(image, direction: FlipDirection.horizontal);
final Image imageRotated = copyRotate(image, angle: 270);
const int lineHeight = highDensityVertical ? 3 : 1;
final List<List<int>> blobs = _toColumnFormat(imageRotated, lineHeight * 8);
}
/// Extract slices of an image as equal-sized blobs of column-format data.
///
/// [image] Image to extract from
/// [lineHeight] Printed line height in dots
List<List<int>> _toColumnFormat(Image imgSrc, int lineHeight) {
final Image image = Image.from(imgSrc); // make a copy
// Determine new width: closest integer that is divisible by lineHeight
final int widthPx = (image.width + lineHeight) - (image.width % lineHeight);
final int heightPx = image.height;
// Create a black bottom layer
final biggerImage = copyResize(image, width: widthPx, height: heightPx);
fill(biggerImage, color: ColorRgb8(0, 0, 0));
// Insert source image into bigger one
compositeImage(biggerImage, image, dstX: 0, dstY: 0);
int left = 0;
final List<List<int>> blobs = [];
while (left < widthPx) {
final Image slice = copyCrop(biggerImage, x: left, y: 0, width: lineHeight, height: heightPx);
final Uint8List bytes = slice.getBytes();
blobs.add(bytes);
left += lineHeight;
}
return blobs;
}
Most likely it's because in v3 all images are RGBA 32-bit, and in v4 it supports a lot of different image formats. Your blobs output probably assumes the old RGBA 32-bit data, and the image you loaded probably is not that. So you should convert the image first:
final Image slice = copyCrop(biggerImage, x: left, y: 0, width: lineHeight, height: heightPx);
final sliceRgba32 = slice.convert(format: Format.uint8, numChannels: 4);
final Uint8List bytes = sliceRgba32.getBytes();
blobs.add(bytes);
left += lineHeight;
Let's just say it didn't work out very well.
I have a png file optimized via https://tinypng.com. When I use
copyResize
with different interpolation, the output file is very different between v3 and v4.Source file:
Output:
I created a reproduction repo.