如何使用Floyd-Steinberg抖动将24位PNG转换为3位PNG?

如何使用Floyd-Steinberg抖动将24位PNG转换为3位PNG? 应该使用java.awt.image.BufferedImage来获取和设置RGB值。

在维基百科上,给出了一个如何将16位转换为8位图像的示例:

 find_closest_palette_color(oldpixel) = (oldpixel + 128) / 256 

基于此,是否有任何关于如何适应上述示例以实现目标的想法?

使用image.getRGB(x, y)image.setRGB(x, y, color)并使用维基百科文章中的伪代码 。 请注意,wiki上的代码没有说明如何“减去”,“添加”和“乘以”颜色。 (下面的T3类处理“颜色”操作。)

下面的代码将生成此屏幕截图:

截图

 class Test { private static BufferedImage floydSteinbergDithering(BufferedImage img) { C3[] palette = new C3[] { new C3( 0, 0, 0), new C3( 0, 0, 255), new C3( 0, 255, 0), new C3( 0, 255, 255), new C3(255, 0, 0), new C3(255, 0, 255), new C3(255, 255, 0), new C3(255, 255, 255) }; int w = img.getWidth(); int h = img.getHeight(); C3[][] d = new C3[h][w]; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) d[y][x] = new C3(img.getRGB(x, y)); for (int y = 0; y < img.getHeight(); y++) { for (int x = 0; x < img.getWidth(); x++) { C3 oldColor = d[y][x]; C3 newColor = findClosestPaletteColor(oldColor, palette); img.setRGB(x, y, newColor.toColor().getRGB()); C3 err = oldColor.sub(newColor); if (x+1 < w) d[y ][x+1] = d[y ][x+1].add(err.mul(7./16)); if (x-1>=0 && y+1 

源代码需要静态类C3中缺少的方法“diff”。 否则,它不编译或工作。

这是缺少的diff方法:

 public int diff(C3 o) { int Rdiff = or - this.r; int Gdiff = og - this.g; int Bdiff = ob - this.b; int distanceSquared = Rdiff*Rdiff + Gdiff*Gdiff + Bdiff*Bdiff; return distanceSquared; } 

您可以使用JAI: http : //java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/Image-manipulation.doc.html

顺便说一句,这是Floyd-Steinberg的video代码和现场演示! 🙂

http://blog.ivank.net/floyd-steinberg-dithering-in-javascript.html