# 使用Floyd-Steinberg抖动算法处理价签图片

Floyd-Steinberg抖动算法简直量身为价签这种低颜色呈现设备准备的。由于价签的墨水屏能够呈现的色彩非常有限，根据型号不同，有的只能显示黑白，有的只能显示黑白红，有的只能显示黑白黄，所以对于一张普通图片，需要将其转换为两色或者三色才能比较好地在价签上展示出来。

public class BMPConverter {

public static RGBTriple[] getPalette(int deviceType) {
final RGBTriple[] palette;

if (deviceType == 0) {
//黑白价签
palette = new RGBTriple[]{
new RGBTriple(0, 0, 0),
new RGBTriple(255, 255, 255)
};
} else if (deviceType == 1) {
//黑白红价签
palette = new RGBTriple[]{
new RGBTriple(0, 0, 0),
new RGBTriple(255, 255, 255),
new RGBTriple(255, 0, 0)
};

} else {
//黑白黄价签
palette = new RGBTriple[]{
new RGBTriple(0, 0, 0),
new RGBTriple(255, 255, 255),
new RGBTriple(255, 255, 0)
};
}
return palette;
}

public static byte[][] floydSteinbergDither(RGBTriple[][] image, RGBTriple[] palette)
{
byte[][] result = new byte[image.length][image[0].length];

for (int y = 0; y < image.length; y++) {
for (int x = 0; x < image[y].length; x++) {
RGBTriple currentPixel = image[y][x];
byte index = findNearestColor(currentPixel, palette);
result[y][x] = index;

for (int i = 0; i < 3; i++)
{
int error = (currentPixel.channels[i] & 0xff) - (palette[index].channels[i] & 0xff);
if (x + 1 < image[0].length) {
image[y+0][x+1].channels[i] =
plus_truncate_uchar(image[y+0][x+1].channels[i], (error*7) >> 4);
}
if (y + 1 < image.length) {
if (x - 1 > 0) {
image[y+1][x-1].channels[i] =
plus_truncate_uchar(image[y+1][x-1].channels[i], (error*3) >> 4);
}
image[y+1][x+0].channels[i] =
plus_truncate_uchar(image[y+1][x+0].channels[i], (error*5) >> 4);
if (x + 1 < image[0].length) {
image[y+1][x+1].channels[i] =
plus_truncate_uchar(image[y+1][x+1].channels[i], (error*1) >> 4);
}
}

}

}
}

return result;
}

private static byte plus_truncate_uchar(byte a, int b) {
if ((a & 0xff) + b < 0) {
return 0;
} else if ((a & 0xff) + b > 255) {
return (byte) 255;
} else {
return (byte) (a + b);
}
}

private static byte findNearestColor(RGBTriple color, RGBTriple[] palette) {
int minDistanceSquared = 255*255 + 255*255 + 255*255 + 1;
byte bestIndex = 0;
for (byte i = 0; i < palette.length; i++) {
int Rdiff = (color.channels[0] & 0xff) - (palette[i].channels[0] & 0xff);
int Gdiff = (color.channels[1] & 0xff) - (palette[i].channels[1] & 0xff);
int Bdiff = (color.channels[2] & 0xff) - (palette[i].channels[2] & 0xff);
int distanceSquared = Rdiff*Rdiff + Gdiff*Gdiff + Bdiff*Bdiff;
if (distanceSquared < minDistanceSquared) {
minDistanceSquared = distanceSquared;
bestIndex = i;
}
}
return bestIndex;
}

}

public class  RGBTriple {
public final byte[] channels;
public RGBTriple() { channels = new byte[3]; }
public RGBTriple(int R, int G, int B)
{ channels = new byte[]{(byte)R, (byte)G, (byte)B}; }
}

• 0
点赞
• 0
评论
• 6
收藏
• 一键三连
• 扫一扫，分享海报

04-05

06-22 8076
04-11 9102
06-11 259
06-10 2722
09-17 2821
06-10 1万+
03-14 963