使用Atkinson抖动算法处理价签图片

找了好久Atkinson的Java实现,始终没找到现成的,只有一个pde的参考:

https://github.com/danielepiccone/dithering_algorithms/blob/master/atkinson_color/atkinson_color.pde

用Java重新写了一下,核心代码如:

public class BMPConverter {

    public static byte[][] atkinsonDither(RGBTriple[][] image, RGBTriple[] palette) {

        int s = 1;
        byte[][] result = new byte[image.length][image[0].length];

        // Scan image
        for (int x = s; x < image.length-2*s; x+=s) {
            for (int y = 0; y < image[x].length-2*s; y+=s) {
                // Calculate pixel
                RGBTriple oldpixel = image[x][y];
                byte index = findNearestColor(oldpixel, palette);
                RGBTriple newpixel = palette[index];
                RGBTriple quant_error = new RGBTriple(oldpixel.getRed() - newpixel.getRed(), oldpixel.getGreen() - newpixel.getGreen(), oldpixel.getBlue() - newpixel.getBlue());
                result[x][y] = index;

                // Atkinson algorithm http://verlagmartinkoch.at/software/dither/index.html
                RGBTriple s1 = image[x+s][y];
                image[x+s][y] = adjustRGB(s1, quant_error);

                RGBTriple s2 = image[x-s][y+s];
                image[x-s][y+s] = adjustRGB(s2, quant_error);

                RGBTriple s3 = image[x][y+s];
                image[x][y+s] = adjustRGB(s3, quant_error);

                RGBTriple s4 = image[x+s][y+s];
                image[x+s][y+s] = adjustRGB(s4, quant_error);

                RGBTriple s5 = image[x+2*s][y];
                image[x+2*s][y] = adjustRGB(s5, quant_error);

                RGBTriple s6 = image[x][y+2*s];
                image[x][y+2*s] = adjustRGB(s6, quant_error);

            }
        }
        return result;
    }

    private static RGBTriple adjustRGB(RGBTriple originalRGB, RGBTriple error) {
        return new RGBTriple((new Double(originalRGB.getRed() +  1.0/8 * error.getRed())).intValue(),
                (new Double(originalRGB.getGreen() + 1.0/8 * error.getGreen())).intValue(),
                (new Double(originalRGB.getBlue() + 1.0/8 * error.getBlue()).intValue()));
    }

    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};
    }

    public byte getRed() {
        return channels[0];
    }

    public byte getGreen() {
        return channels[1];
    }

    public byte getBlue() {
        return channels[2];
    }
}

显示的效果如:

转载于:https://my.oschina.net/u/4042451/blog/3060817

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值