使用霍夫曼树进行图像压缩

时间:2016-12-20 08:16:32

标签: java image huffman-code

所以我最近构建了一个Huffman树,它可以很好地编码文本。现在我想尝试看看我是否可以压缩图像。显然,差异很小的图像(如抽象图像)应该更好地压缩。我的问题是,我是否正在考虑这一点。让我们说我得到了一个786x463像素大的jpg图像。每个像素具有3个颜色值,每个颜色值可以是256种不同的颜色,因此是8位。我们有三种颜色,RGB,所以每个像素都有效地24位全部。所以(786x463)* 24 = 853 40 16位,约为1 Mb。

现在我可以遍历所有像素,并将三个颜色值放在一个列表中,然后计算该列表中每种颜色的出现次数,并删除重复项并将它们放在我的树中。

private void saveColors() {
    BufferedImage img = readImage(url);
    int width = img.getWidth();
    int height = img.getHeight();
    int size = (width * height) * 3;
    pixels = new ArrayList<Integer>(size);

    WritableRaster inraster = img.getRaster();
    for (int i = 0; i < width; i++)
        for (int j = 0; j < height; j++) {
            pixels.add(inraster.getSample(i, j, 0));
            pixels.add(inraster.getSample(i, j, 1));
            pixels.add(inraster.getSample(i, j, 2));
        }
    countColors();
}

/**
 * Counts occurences and removes duplicates
 */
private void countColors() {
    List<Integer> duplicateRemoved;
    duplicateRemoved = new ArrayList<Integer>(pixels);

    Set<Integer> hs = new HashSet<Integer>();
    hs.addAll(duplicateRemoved);
    duplicateRemoved.clear();
    duplicateRemoved.addAll(hs);

    pixelFreq = new int[duplicateRemoved.size()];
    pixelArr = new int[duplicateRemoved.size()];

    for (int i = 0; i < pixelArr.length; i++) {
        int p = duplicateRemoved.get(i);
        int count = Collections.frequency(pixels, p);
        pixelArr[i] = p;
        pixelFreq[i] = count;
    }
//Build tree...
}

所以我试着对这张照片进行编码:[只是黑白1

编码结果给了我这个:

color   Freq    Code   bits
'0' -- 4410 -- '0010'--17640
'1' -- 1185 -- '001001'--7110
'2' -- 858 -- '00100'--4290
'3' -- 591 -- '00100101'--4728
'4' -- 315 -- '0010010101'--3150
'5' -- 180 -- '0010010101010'--2340
'6' -- 75 -- '0010001010010'--975
'7' -- 30 -- '00100010100100'--420
'8' -- 9 -- '0010001010010000'--144
'246' -- 3 -- '001000101001000'--45
'247' -- 15 -- '001000101001000'--225
'248' -- 84 -- '0010001010'--840
'249' -- 138 -- '001001010101'--1656
'250' -- 273 -- '0010001010'--2730
'251' -- 480 -- '0010001'--3360
'252' -- 1227 -- '0001'--4908
'253' -- 1749 -- '00010'--8745
'254' -- 2475 -- '00'--4950
'255' -- 1077657 -- '0'--1077657
 Original compressed reduction percent
8734032--1145913---7588119--86.879906%

这似乎是合理的,大多数情况下会出现白色并且得到最小的代码,其中黑色代码稍微大一些。 现在你可以看到,总的比特数最终是1145913。 所以我们计算差异:8534016 - 1145913 = 7388103,大约是0.4 Mb。所以差异大约为0.6 Mb,减少了60%。

所以我的问题是,我在考虑这个问题吗?我的意思是计算每个像素的所有颜色值?

0 个答案:

没有答案