Skip to content

Commit

Permalink
fix ditherImage
Browse files Browse the repository at this point in the history
  • Loading branch information
brendan-duncan committed May 11, 2024
1 parent 180bb2c commit f12029a
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 22 deletions.
28 changes: 16 additions & 12 deletions lib/src/filter/dither_image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ const _ditherKernels = [

/// Dither an image to reduce banding patterns when reducing the number of
/// colors.
/// Derived from http://jsbin.com/iXofIji/2/edit
Image ditherImage(Image image,
{Quantizer? quantizer,
DitherKernel kernel = DitherKernel.floydSteinberg,
Expand All @@ -80,24 +81,27 @@ Image ditherImage(Image image,
final indexedImage =
Image(width: width, height: height, numChannels: 1, palette: palette);

final pIter = image.iterator..moveNext();
final imageCopy = image.clone();

final pIter = imageCopy.iterator..moveNext();

var index = 0;
for (var y = 0; y < height; y++) {
if (serpentine) direction = direction * -1;
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, ++index, pIter.moveNext()) {
for (var x = x0; x != x1; x += direction, pIter.moveNext()) {
// Get original color
final pc = pIter.current;
final r1 = pc[0].toInt();
final g1 = pc[1].toInt();
final b1 = pc[2].toInt();

// Get converted color
var idx = quantizer.getColorIndexRgb(r1, g1, b1);
indexedImage.setPixelRgb(x, y, idx, 0, 0);
final idx = quantizer.getColorIndexRgb(r1, g1, b1);
indexedImage.setPixelIndex(x, y, idx);

final r2 = palette.get(idx, 0);
final g2 = palette.get(idx, 1);
Expand All @@ -118,13 +122,13 @@ Image ditherImage(Image image,
final y1 = ds[i][2].toInt();
if (x1 + x >= 0 && x1 + x < width && y1 + y >= 0 && y1 + y < height) {
final d = ds[i][0];
idx = index + x1 + (y1 * width);
idx *= 4;
final p2 = image.getPixel(x1, y1);
final nx = x + x1;
final ny = y + y1;
final p2 = imageCopy.getPixel(nx, ny);
p2
..r = max(0, min(255, (p2.r + er * d).toInt()))
..g = max(0, min(255, (p2.g + er * d).toInt()))
..b = max(0, min(255, (p2.b + er * d).toInt()));
..r = p2.r + er * d
..g = p2.g + eg * d
..b = p2.b + eb * d;
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions test/_test_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import 'package:archive/archive.dart';
import 'package:image/image.dart';
import 'package:test/test.dart';

final testOutputPath = '${Directory.systemTemp.createTempSync().path}/out';
//const testOutputPath = './_out';
//final testOutputPath = '${Directory.systemTemp.createTempSync().path}/out';
const testOutputPath = './_out';

int hashImage(Image image) {
var hash = 0;
Expand Down
8 changes: 4 additions & 4 deletions test/filter/dither_image_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ void main() {
final bytes = File('test/_data/png/buck_24.png').readAsBytesSync();
final i0 = decodePng(bytes)!;

var id = ditherImage(i0);
File('$testOutputPath/filter/dither_FloydSteinberg.png')
var id = ditherImage(i0, kernel: DitherKernel.atkinson);
File('$testOutputPath/filter/dither_Atkinson.png')
..createSync(recursive: true)
..writeAsBytesSync(encodePng(id));

id = ditherImage(i0, kernel: DitherKernel.atkinson);
File('$testOutputPath/filter/dither_Atkinson.png')
id = ditherImage(i0);
File('$testOutputPath/filter/dither_FloydSteinberg.png')
..createSync(recursive: true)
..writeAsBytesSync(encodePng(id));

Expand Down
20 changes: 16 additions & 4 deletions test/filter/quantize_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,28 @@ void main() {
final bytes = File('test/_data/png/buck_24.png').readAsBytesSync();

final i0 = decodePng(bytes)!;
quantize(i0, numberOfColors: 32, method: QuantizeMethod.octree);
final q0 = quantize(i0, numberOfColors: 32, method: QuantizeMethod.octree);
File('$testOutputPath/filter/quantize_octree.png')
..createSync(recursive: true)
..writeAsBytesSync(encodePng(i0));
..writeAsBytesSync(encodePng(q0));

final i0_ = decodePng(bytes)!;
final q0_ = quantize(i0_, numberOfColors: 32, method: QuantizeMethod.octree, dither: DitherKernel.floydSteinberg);
File('$testOutputPath/filter/quantize_octree_dither.png')
..createSync(recursive: true)
..writeAsBytesSync(encodePng(q0_));

final i1 = decodePng(bytes)!;
quantize(i1, numberOfColors: 32);
final q1 = quantize(i1, numberOfColors: 32);
File('$testOutputPath/filter/quantize_neural.png')
..createSync(recursive: true)
..writeAsBytesSync(encodePng(i1));
..writeAsBytesSync(encodePng(q1));

final i2 = decodePng(bytes)!;
final q2 = quantize(i2, numberOfColors: 32, dither: DitherKernel.floydSteinberg);
File('$testOutputPath/filter/quantize_neural_dither.png')
..createSync(recursive: true)
..writeAsBytesSync(encodePng(q2));
});
});
}

0 comments on commit f12029a

Please sign in to comment.