我一直在努力尝试使用PNGJ做等效的代码。我不想使用ImageIO. read
和BufferedImage.getRGB
。相反,我想纯粹使用PNGJ获取像素。下面的代码是我的ImageIO BufferedImage版本。
BufferedImage bi = ImageIO.read( imageFile );
...
int[] pixels = new int[arrSize];
bi.getRGB( 0, 0, width, height, pixels, 0, width );
我想要像PNGJ那样的东西
lint = (ImageLineInt) reader.readRow();
scanLine = lint.getScanline();
...
???
以下是我的测试图像详细信息:
ImageInfo[cols=1530,rows=1980,bitDepth=8,Channel=3,BitsPixel=24,bytesPixel=3,bytesPerRow=4590,samplesPerRow=4590,samplesPerRowP=4590,alpha=false,greyscale=false,indexed=false,packed=false]
你可以使用BuffereImage获得像素。获取RGB是访问像素值最慢的方法之一。你想要的是访问数据缓冲区。
BufferedImage bi = ImageIO.read( imageFile );
byte[] pixels = ((DataBufferByte)bi.getRaster().getDataBuffer()).getData() ;
您只需小心图像编码(字节、Int或短)。
到目前为止,这是我发现的。https://code.google.com/p/pngj/wiki/FAQ
如何读取/写入像素值?每个PngReader的readRow()调用都返回一个IImageLine,它代表一个PNG图像行;具体实现是可扩展的。但是默认包含的实现(PngReader或PngReaderInt)返回ImageLineInt。这个类包装了一个scaline(getScanline()),它是一个int[]数组。该数组的每个元素对应一个图像样本;因此,数组长度(至少)为列x通道。
另一种格式是ImageLineByte,除了将每个样本存储在一个字节中之外,它是相同的(优点:内存使用更少,8位图像的最佳速度;缺点:如果图像是每通道16位,则会丢失分辨率,而且做算术更麻烦——Java中的字节是有符号的)。
扫描线内示例值的布局如下:
对于真彩色图像,RGB/RGBA样本按RGB(A)顺序排列:RGB R G B。。。(没有阿尔法)或RGB A RGB A。。。(使用alpha);这些值不按比例缩放:只有当bitdepth=8时,它们才会在0-255范围内(如果bitdepth=16,则为0-65535;如果bitdepth=4,则为0-15,以此类推)。对于索引图像,每个样本值对应于调色板索引I。。。。对于灰度G/GA图像,它是灰度值G。。。(没有阿尔法)或G A G A。。。(使用alpha)。
下面是我使用的代码,可以在以后提供给BuffereImage(具有透明度。半透明):
PngReader reader = new PngReader( inputPNGFile );
arrSize = (int) reader.imgInfo.getTotalPixels();
width = reader.imgInfo.cols;
height = reader.imgInfo.rows;
channels = reader.imgInfo.channels;
ImageLineInt lint;
while ( reader.hasMoreRows() ) {
lint = (ImageLineInt) reader.readRow();
scanLine = lint.getScanline();
for ( i = 0; i < width; i++ ) {
offset = i * channels;
// Adjust the following code depending on your source image.
// I need the to set the alpha channel to 0xFF000000 since my destination image
// is TRANSLUCENT : BufferedImage bi = CONFIG.createCompatibleImage( width, height, Transparency.TRANSLUCENT );
// my source was 3 channels RGB without transparency
nextPixel = ( scanLine[offset] << 16 ) | ( scanLine[offset + 1] << 8 ) | ( scanLine[offset + 2] ) | 0xFF000000;
// I'm placing the pixels on a memory mapped file
mem.putInt( nextPixel );
}
}
正如Zek的回答所指出的,PNGJ与BufferedImage
不同:它更低级,因为它不会尝试以抽象的通用格式(独立于具体的PNG格式)表示图像像素,而是为您提供直接映射到PNG格式和颜色模型的格式值。
这意味着,例如,如果PNG图像是RGB,您将获得三个RGB组件作为连续(整数)值。如果PNG图像被索引,您将获得索引(指向调色板的整数值)。如果PNG图像是灰度的,那么灰度值将作为单个整数。等
如果您想以更一般的方式处理像素值(无论基础颜色模型如何,都给我RGB值),您可以自己进行转换,或者利用ImageLineHelper类中的helper方法。具体来说,请查看方法convert2rgba()
和getPixelARGB8()
。
不过,请记住,这个类只是一组助手方法,可能对您有用,也可能没有。很难对RGB进行完全通用的转换,因为有很多复杂的问题和启发——PNG允许多种透明模式、深度、颜色空间。。。(如果图像深度为2比特怎么办?如果是16比特怎么办?如果它有一个非标准的颜色轮廓或伽马校正,或者它有一个单一的透明块,或者…等等)?如果你想支持完整的PNG图像集,几乎需要了解其基本格式和复杂性。
(但是,但是......BufferedImage
这样做,完全笼统,没有歧义,没有问题,你说?不完全是)
如果你可以限制你的颜色模型(RGB,8位,没有alpha)(并且你没有透明度TRNS块或gamma特性,或者不在乎),那么它非常简单:
for (int i = 0,j=0 ; i < reader.imgInfo.cols; i++, j+=channels ) {
int r = scanLine[j];
int g = scanLine[j+1];
int b = scanLine[j+2];
// ...
}
免责声明:我是PNGJ编码员。
问题内容: 我正在做一些图像处理,我想分别读取JPEG和PNG图像中的每个像素值。 在我的部署方案中,使用第3方库对我来说很尴尬(因为我对目标计算机的访问受到限制),但是我假设没有用于读取JPEG / PNG的标准C或C ++库… 因此,如果您知道 不 使用库的方法,那就太好了,如果没有,那么仍然欢迎回答! 问题答案: C标准中没有标准库可以读取文件格式。 但是,大多数程序,尤其是在Linux平台
问题内容: 如何使用PIL检测PNG图像是否具有透明的Alpha通道? 通过上面的代码,我们知道PNG图像是否不具有Alpha通道,但是如何获得Alpha值? 我没有在PIL网站上描述的img.info词典中找到“透明”键 我正在使用Ubuntu和zlib1g,已经安装了zlibc软件包。 问题答案: 要获取RGBA图像的alpha层,您需要做的是: 要么 有一种设置Alpha层的方法: 透明度键
问题内容: 我正在使用Tensorflow构建标准的图像分类模型。为此,我有输入图像,每个图像都分配了一个标签({0,1}中的数字)。因此,可以使用以下格式将数据存储在列表中: 我想使用TensorFlow的排队系统读取我的数据并将其输入到我的模型中。忽略标签,可以使用和轻松实现。这里的代码: 但是,在该过程中标签丢失了,因为图像数据作为输入管道的一部分被有意地改组了。通过输入队列将标签和图像数据
我有一个大问题,试图将一个大的科学图像(7MB)16位PNG图像转换为JPG,以便压缩它并检查Python中的任何最终工件。原始图像可在以下位置找到:https://postimg.cc/p5PQG8ry在这里阅读其他答案时,我尝试了枕头和OpenCV,但没有成功。我得到的唯一东西是一张白色的床单。我做错了什么?注释行是使用Python读取16位PNG图像文件的尝试,但似乎不适用于生成数据类型错误
我试图用处理docx文件。只是简单地读取然后写入文件(现在)。这是我的简单代码: 问题是输入文件的头文件中有一个小图像。因此,在使用POI处理输入文件并在Microsoft Word中打开输出文件后,我收到损坏的文件错误: 一切工作在OO Writer,但不是在办公室。 问题是:怎么了?apache POI是否不处理头文件中包含图像的文件?你知道解决这个问题的方法吗? 我需要使用,我不考虑其他工具
问题内容: 我正在使用Tkinter编写GUI,并希望在中显示png文件。所以我有一些这样的代码: 这段代码 可以在我的Linux机器上正确运行 。但是,当我在Windows计算机上运行它时,它会失败。我还在其他几台机器(包括Windows和Linux)上进行了测试,但始终失败。 追溯为: 如果删除源代码,则回溯将变为: 那么,我应该怎么做才能使其支持png文件? 问题答案: tkinter仅支持