ditherImage function
Image
ditherImage(
- Image image, {
- Quantizer? quantizer,
- DitherKernel kernel = DitherKernel.floydSteinberg,
- bool serpentine = false,
Dither an image to reduce banding patterns when reducing the number of colors. Derived from http://jsbin.com/iXofIji/2/edit
Implementation
Image ditherImage(Image image,
{Quantizer? quantizer,
DitherKernel kernel = DitherKernel.floydSteinberg,
bool serpentine = false}) {
quantizer ??= NeuralQuantizer(image);
if (kernel == DitherKernel.none) {
return quantizer.getIndexImage(image);
}
final ds = _ditherKernels[kernel.index];
final height = image.height;
final width = image.width;
var direction = serpentine ? -1 : 1;
final palette = quantizer.palette;
final indexedImage =
Image(width: width, height: height, numChannels: 1, palette: palette);
final imageCopy = image.clone();
for (var y = 0; y < height; y++) {
if (serpentine) {
direction = direction * -1;
}
final x0 = direction == 1 ? 0 : width - 1;
final x1 = direction == 1 ? width : 0;
for (var x = x0; x != x1; x += direction) {
// Get original color
final pc = imageCopy.getPixel(x, y);
final r1 = pc[0].toInt();
final g1 = pc[1].toInt();
final b1 = pc[2].toInt();
// Get converted color
final idx = quantizer.getColorIndexRgb(r1, g1, b1);
indexedImage.setPixelIndex(x, y, idx);
final r2 = palette.get(idx, 0);
final g2 = palette.get(idx, 1);
final b2 = palette.get(idx, 2);
final er = r1 - r2;
final eg = g1 - g2;
final eb = b1 - b2;
if (er == 0 && eg == 0 && eb == 0) {
continue;
}
final i0 = direction == 1 ? 0 : ds.length - 1;
final i1 = direction == 1 ? ds.length : 0;
for (var i = i0; i != i1; i += direction) {
final x1 = ds[i][1].toInt();
final y1 = ds[i][2].toInt();
if ((x1 + x) >= 0 &&
(x1 + x) < width &&
(y1 + y) >= 0 &&
(y1 + y) < height) {
final d = ds[i][0];
final nx = x + x1;
final ny = y + y1;
final p2 = imageCopy.getPixel(nx, ny);
p2
..r = p2.r + er * d
..g = p2.g + eg * d
..b = p2.b + eb * d;
}
}
}
}
return indexedImage;
}