我可以使用libjpeg读取带有alpha通道的JPEG吗?

时间:2011-06-02 09:50:10

标签: java jpeg file-format libjpeg color-space

关于alpha通道的JPEG是否有效似乎存在争议。我一直认为正确的答案是that in the JPEG FAQ,基本上是“否”。 (another question on Stack Overflow重申了这一点。)

然而,Sun的ImageIO库中的Java的JPEGImageWriter将很乐意使用alpha通道编写和读取灰度和RGB图像,即使在Linux上我几乎没有应用程序,我已经尝试过正确地加载这些JPEG。这在过去曾被报道为一个错误,但Sun的反应是these are valid files

  

这不是Image I / O错误,而是其他应用程序的缺陷   提交者提到。 IIO JPEGImageWriter能够用图像写入图像   包含alpha通道的颜色模型(在IJG原生中引用   源代码作为“NIFTY”颜色空间,如RGBA,YCbCrA等),但许多应用程序都不知道这些颜色空间。所以即使这些图像   由IIO JPEG编写器编写的符合JPEG规范(其中   对各种颜色空间可能性视而不见,有些应用可能没有   识别包含alpha通道的颜色空间并可能抛出一个   错误或呈现损坏的图像,如提交者所述。

     

开发人员希望保持与其他alpha-unaware的兼容性   应用程序应编写不包含alpha通道的图像(例如   TYPE_INT_RGB)。希望具有写/读图像能力的开发人员   包含JPEG格式的Alpha通道可以使用Image I / O来实现   API,但需要注意的是,许多原生应用程序并不完全   符合YCbCrA和RGBA格式。

     

有关详细信息,请参阅图像I / O JPEG元数据格式规范和使用说明:   http://java.sun.com/j2se/1.4.1/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html

     

关闭为“不是错误”。     xxxxx @ xxxxx 2003-03-24

我正在使用一个创建这些文件的Java应用程序,并希望编写一些可以尽快加载这些文件的C代码。 (基本上问题是Java ImageIO库在解压缩这些文件时速度非常慢,我们希望通过JNI用本机代码替换加载器来改善这一点 - 这是目前的性能瓶颈。)

这里有一些示例文件 - 向coulrophobic的所有人道歉:

在这里,您可以看到尝试使用我认为使用的各种Linux软件查看灰度+ alpha和RGB + alpha图像的结果libjpeg

grayscale image with alpha channel view with various programs http://mythic-beasts.com/~mark/all-alpha-bridges.png

RGB image with alpha channel view with various programs http://mythic-beasts.com/~mark/all-alpha-clowns.png

因此看起来好像在每种情况下都会误解色彩空间。 jpeglib.h中唯一允许的值为:

/* Known color spaces. */

typedef enum {
        JCS_UNKNOWN,            /* error/unspecified */
        JCS_GRAYSCALE,          /* monochrome */
        JCS_RGB,                /* red/green/blue */
        JCS_YCbCr,              /* Y/Cb/Cr (also known as YUV) */
        JCS_CMYK,               /* C/M/Y/K */
        JCS_YCCK                /* Y/Cb/Cr/K */
} J_COLOR_SPACE;

......看起来并不乐观。

如果我使用example.c的{​​{1}}稍加修改版本加载这些图片,则读取标题后每张图片的libjpegcinfo.jpeg_color_space值如下:

cinfo.out_color_space

所以,我的问题是:

  • 可以使用libjpeg正确读取这些文件吗?
  • 如果没有,是否有可以使用的替代C库来处理它们?

显然,对于更普遍的问题,至少有两种其他解决方案:

  1. 更改软件以输出普通JPEG +表示Alpha通道的PNG文件
  2. 以某种方式改善Sun的ImageIO的性能
  3. ...但第一个会涉及很多代码更改,而且不清楚如何处理后者。在任何情况下,我认为如何使用gray-normal.jpg: jpeg_color_space is JCS_GRAYSCALE, out_color_space is JCS_GRAYSCALE gray-alpha.jpg: jpeg_color_space is JCS_CMYK, out_color_space is JCS_CMYK rgb-normal.jpg: jpeg_color_space is JCS_YCbCr, out_color_space is JCS_RGB rgb-alpha.jpg: jpeg_color_space is JCS_CMYK, out_color_space is JCS_CMYK 加载此类文件的问题可能是更普遍的兴趣之一。

    我们非常感谢任何建议。

3 个答案:

答案 0 :(得分:2)

即使您将图像存储为4通道jpeg图像,我也不知道如何在jpeg文件中指定颜色格式。

JFIF标准假定为YCbCr。

答案 1 :(得分:1)

您是否已尝试libjpeg-turbo?它应该能够解码RGBA,并且已经有一个Java包装器。

答案 2 :(得分:1)

我尝试在具有alpha通道的彩色图像上运行libjpeg-turbo,并且已经将java的ImageIO保存为jpeg。

这是我为linux 64位编译libjpeg-turbo的方法:

$ autoreconf -fiv
$ mkdir build
$ cd build
$ sh ../configure --with-java CPPFLAGS="-I$JAVA_HOME/include -I$JAVA_HOME/include/linux"
$ make
$ cd ..
$ mkdir my-install
$ cd build
$ make install prefix=$PWD/../my-install libdir=$PWD/../my-install/lib64

这就是我用正确的库路径和类路径运行斐济的方法,包括libjpeg-turbo:

$ cd Programming/fiji
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/../java/libjpeg-turbo/libjpeg-turbo/my-install/lib64
$ ./fiji -cp $PWD/../java/libjpeg-turbo/libjpeg-turbo/my-install/classes/turbojpeg.jar

这是一个小的jython脚本来读取这样的jpeg + alpha文件:

######
path = "/home/albert/Desktop/t2/trakem2.1263462814399.1347985440.1111111/trakem2.mipmaps/0/17.07may04b_GridID02043_Insertion001_00013gr_00005sq_00014ex.tif.jpg"

from org.libjpegturbo.turbojpeg import TJDecompressor, TJ
from java.io import File, FileInputStream
from java.awt.image import BufferedImage
from jarray import zeros

f = File(path)
fis = FileInputStream(f)
b = zeros(fis.available(), 'b')
print len(b)
fis.read(b)
fis.close()

d = TJDecompressor(b)
print d.getWidth(), d.getHeight()
bi = d.decompress(d.getWidth(), d.getHeight(), BufferedImage.TYPE_INT_ARGB, 0)

ImagePlus("that", ColorProcessor(bi)).show()
####

问题:无论我使用什么标志(在解压缩调用中为'0')来自TJ类(参见http://libjpeg-turbo.svn.sourceforge.net/viewvc/libjpeg-turbo/trunk/java/doc/org/libjpegturbo/turbojpeg/TJ.html),我都无法加载jpeg。

以下是错误消息:

Started turbojpeg.py at Thu Jun 02 12:36:58 EDT 2011
Traceback (most recent call last):
  File "", line 15, in 
    at org.libjpegturbo.turbojpeg.TJDecompressor.decompressHeader(Native Method)
    at org.libjpegturbo.turbojpeg.TJDecompressor.setJPEGImage(TJDecompressor.java:89)
    at org.libjpegturbo.turbojpeg.TJDecompressor.(TJDecompressor.java:58)
    at sun.reflect.GeneratedConstructorAccessor10.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.python.core.PyReflectedConstructor.constructProxy(PyReflectedConstructor.java:210)

java.lang.Exception: java.lang.Exception: tjDecompressHeader2(): Could not determine subsampling type for JPEG image 

所以似乎libjpeg-turbo无法读取由ImageIO保存的alpha的jpeg,或者在“解压缩”调用中有一个非常不明显的设置我无法理解。