10

关于带有 alpha 通道的 JPEG 是否有效似乎存在一些争论。我一直认为正确的答案是在 JPEG FAQ中,基本上是“否”。(这在 Stack Overflow 上的另一个问题中得到了重申。)

但是,Sun 的 ImageIO 库中的 Java JPEGImageWriter 将愉快地使用 alpha 通道写入和读取灰度和 RGB 图像,即使到目前为止我尝试过的 Linux 上几乎没有应用程序可以正确加载此类 JPEG。这在过去被报告为一个错误,但 Sun 的回应是这些文件是有效的:

这不是 Image I/O 错误,而是提交者提到的其他应用程序的缺陷。IIO JPEGImageWriter 能够使用包含 alpha 通道的颜色模型编写图像(在 IJG 原生源代码中称为“NIFTY”颜色空间,例如 RGBA、YCbCrA 等),但许多应用程序并不知道这些色彩空间。因此,即使 IIO JPEG 编写器编写的这些图像符合 JPEG 规范(对各种颜色空间的可能性视而不见),某些应用程序可能无法识别包含 alpha 通道的颜色空间,并可能引发错误或呈现损坏的图片,正如提交者描述的那样。

希望与这些其他不知道 alpha 的应用程序保持兼容性的开发人员应该编写不包含 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 用本机代码替换加载器以改进这一点 - 目前这是一个性能瓶颈。)

这里有一些示例文件 - 向任何有恐惧症的人道歉

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

带有各种程序的 alpha 通道视图的灰度图像 http://mythic-beasts.com/~mark/all-alpha-bridges.png

具有各种程序的 Alpha 通道视图的 RGB 图像
(来源:mythic-beasts.com 上的标记

所以看起来色彩空间在每种情况下都被误解了。中唯一允许的值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如果我使用from的略微修改版本加载这些图像,则读取标题后每个图像的和libjpeg值如下:cinfo.jpeg_color_spacecinfo.out_color_space

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

所以,我的问题是:

  • 可以使用 libjpeg 正确读取这些文件吗?
  • 如果没有,我可以使用替代 C 库来应对它们吗?

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

  1. 更改软件以输出普通 JPEG + 表示 Alpha 通道的 PNG 文件
  2. 以某种方式提高 Sun 的 ImageIO 的性能

...但第一个将涉及大量代码更改,并且不清楚如何处理后者。无论如何,我认为如何使用libjpeg来加载此类文件的问题可能是更普遍的兴趣之一。

任何建议将不胜感激。

4

3 回答 3

2

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

JFIF 标准假定为 YCbCr。

于 2011-06-06T08:21:54.290 回答
1

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

于 2011-06-02T10:03:27.897 回答
1

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

这就是我为 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

这就是我使用正确的库路径和类路径运行 Fiji 的方式,包括 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 文件:

######
路径=“/home/albert/Desktop/t2/trakem2.1263462814399.1347985440.1111111/trakem2.mipmaps/0/17.07may04b_GridID02043_Insertion001_00013gr_00005sq_00014ex.tif.jpg”

从 org.libjpegturbo.turbojpeg 导入 TJDecompressor, TJ
从 java.io 导入文件,FileInputStream
从 java.awt.image 导入 BufferedImage
从 jarray 导入零

f = 文件(路径)
fis = FileInputStream(f)
b = 零(fis.available(),'b')
打印长度(b)
fis.read(b)
fis.close()

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

ImagePlus("那个", ColorProcessor(bi)).show()
####

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

这是错误消息:

于 2011 年 6 月 2 日星期四 12:36:58 EDT 开始 turbojpeg.py
回溯(最近一次通话最后):
  文件“”,第 15 行,在
    在 org.libjpegturbo.turbojpeg.TJDecompressor.decompressHeader(本机方法)
    在 org.libjpegturbo.turbojpeg.TJDecompressor.setJPEGImage(TJDecompressor.java:89)
    在 org.libjpegturbo.turbojpeg.TJDecompressor.(TJDecompressor.java:58)
    在 sun.reflect.GeneratedConstructorAccessor10.newInstance(未知来源)
    在 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    在 java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    在 org.python.core.PyReflectedConstructor.constructProxy(PyReflectedConstructor.java:210)

java.lang.Exception:java.lang.Exception:tjDecompressHeader2():无法确定JPEG图像的子采样类型

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

于 2011-06-02T16:43:45.673 回答