如何解压缩png文件

时间:2014-01-08 20:07:09

标签: java image image-processing png

我得到图像png,这个图像已经使用以下方法压缩:

前两个像素和所有奇数像素都是假像素:

  • 第一个像素实际上是一个整数,表示构建解压缩图像时必须重复的像素颜色总数;
  • 第二个像素是一个整数,它确定一次解压缩后的图像高度(其宽度与压缩图像的宽度相同);
  • 第三像素和所有后续奇数像素(n> = 1的像素[2n +1])是表示对后续像素执行的重复次数的整数(像素[2n + 2],其中n> = 1)。

我试图获取有关PNG文件的信息。

BufferedImage img= ImageIO.read(new File("D://rle.png"));
        Raster raster=img.getData();
        int w=raster.getWidth();
        int h=raster.getHeight();

enter image description here

我正在寻找获取像素数据的最快方法以及使用此方法解压缩此图像的方法。

1 个答案:

答案 0 :(得分:1)

您有过,或者您没有给过(或者没有给我们)正确的拆包说明,或者(可能)此图片在发布之前或之后经过了一些处理,例如重新取样或调整大小这里。

  • 图像是常规的真彩色+ alpha PNG,258 x 98像素。
  • 根据其“tEXt”,它是使用“Software:Microsoft Office”创建的。它包含一个1字节的sRGB块,其余的都是IDAT块 - 普通数据。
  • 普通数据解压缩为101234字节,这是图像大小的正确数字。

照顾预赛。现在解码原始数据;这里出现了差异。

  • “第一个像素实际上是一个整数” - “第一个像素”值为01 5A A5 FF。最后一个字节FF 重要;它是图像alpha,对于所有像素都是FF。其余字节可以读作Big Endian(10,836,481)或Little Endian(88,741)。
  • “第二个像素是确定高度的整数” - “第二个像素”值为08 08 83 FF。这将是526,467或8,587,272像素的“高度” - 请选择。
  • “第三个像素[...]是表示重复次数的整数”,第三个像素的RGBA值为1C 19 2E FF。你能指出哪个字节是'整数'吗?挑选任何一个都会产生不良结果(图像不是预期的'尺寸',并且无论如何都无法识别为图像);使用完整的3字节值1,841,454或3,021,084对于普通的RLE重复值来说似乎有点过分。

获取正确图像的链接

好的,它符合原始规范。第一个'像素'值将被解释为3字节整数Big Endian。第一个值是25,258 - 要解压缩的重复/数据对的数量。下一个值是400,即新的图像高度。请注意,提供两者实际上是多余的;但你应该用两者来验证你的算法。

在您自己的尝试中,您正在获取指向“原始数据”(正确)并读取原始宽度(也正确)的指针。但是,正如指南所述,应该从原始数据中读取 height

编写一个函数read_3bytes_as_int,返回要读取的下一个“值”。使用它来获得(a)'解包'长度,(b)新高度,以及(c)每个重复计数。最后一个应该是循环:读取重复计数,然后读取RGB像素并将其重复写入输出文件。记下您读取的像素/对的数量,以便知道何时停止。