JAVA | PNG AVG和Paeth过滤器导致压缩图像上出现线条

时间:2018-08-13 22:50:23

标签: java image image-processing encoding png

我正在实现Java PNG编码器。我在对AVG和Paeth过滤器进行编码时遇到了问题。

我知道我的问题出在计算的某处(使用字节进行计算),但是我只是找不到正确的设置来使其工作。

这些是我的过滤器,然后是原始img的图片以及每一个的最终结果。

在此先感谢您提供的任何帮助!

过滤器:

    /*
 * Filter based on diff with AVG of previous & above pixels. First pixel in
 * each line, and the first line, are copied as is.
 * pixdat[] = the original img byte array
 * @param1: scanLines: 1 line of bytes (line length=width*3 (3b per
 * pixel)
 * @param2: line: current line in original image data
 * @return resulting lines of filtered values (byte array)
 */
protected byte[] filterAVG(byte[] scanLine,int line) {
    byte[] temp = new byte[scanLine.length];
    temp[0] = scanLine[0];
    temp[1] = scanLine[1];
    temp[2] = scanLine[2];
    double avg;
    for (int i = 3; i < scanLine.length; i++) {
        avg=(Math.floor((scanLine[i - 3] + pixdat[(line-1)*width*3+i])/2));
        temp[i] = (byte) (scanLine[i] - avg);

    }

    return temp;
}

/*
 * Filter based on paeth linear equation; First pixel in each line, and the
 * first line, are copied as is. if a=prev pixel, b= pixel above, c = pixel
 * above and to the left then: p=a+b-c. answer=the smallest diff between
 * pa,pb,pc.
 * 
 * @param scanLines: 1 or more lines of bytes (line length=width*3 (3b per
 * pixel)
 * @param2: line: current line in original image data
 * @return resulting lines of filtered values (byte array)
 */
protected byte[] filterPaeth(byte[] scanLine,int line) {
    byte[] temp = new byte[scanLine.length];
    temp[0]=scanLine[0];
    temp[1]=scanLine[1];
    temp[2]=scanLine[2];
    for (int i = 3; i < scanLine.length; i++) {
            temp[i]=(byte) ((scanLine[i]&0xff-paethPredictor(scanLine, i, line)));
        }

    return temp;
}
protected int paethPredictor(byte[] temp,int i,int line){
            int p,pa,pb,pc;
            int a = temp[i - 3], b = pixdat[(line-1)*width*3+i], c = pixdat[(line-1)*width*3+i - 3];
            p =  (a + b - c);        //; initial estimate
            pa = Math.abs(p&0xff - a&0xff);      //; distances to a, b, c
            pb = Math.abs(p&0xff - b&0xff);
            pc = Math.abs(p&0xff - c&0xff);
            // return nearest of a,b,c,
            // breaking ties in order a,b,c.
            if (pa <= pb && pa <= pc) return a;
            else if (pb <= pc)  return b;
            else return c;
}

图片: original , AVG , Paeth

0 个答案:

没有答案