【问题标题】:Can I use libjpeg to read JPEGs with an alpha channel?我可以使用 libjpeg 读取带有 alpha 通道的 JPEG 吗?
【发布时间】:2011-09-06 23:03:03
【问题描述】:

关于带有 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 的开发人员保持兼容性 应用程序应该编写不包含 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 的任何人道歉:

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

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


(来源:mark at 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;

...看起来不太乐观。

如果我使用libjpegexample.c 的略微修改版本加载这些图像,则读取标题后每个图像的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 加载此类文件的问题可能是更普遍的兴趣之一。

任何建议将不胜感激。

【问题讨论】:

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


    【解决方案1】:

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

    JFIF 标准假定 YCbCr。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 不,我不知道!感谢您的建议。
      • 不幸的是,我无法让 libjpeg-turbo 正确解码这些图像,但我接受这是最有帮助的答案。
      • 只需阅读 libjpegturbo 的文档。它说,下降第 4 频道。因此,如果我理解正确,则没有 alpha。
      【解决方案3】:

      我尝试在具有 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
      

      这是一个读取此类 jpeg+alpha 文件的小型 jython 脚本:

      ###### 路径=“/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 类(请参阅http://libjpeg-turbo.svn.sourceforge.net/viewvc/libjpeg-turbo/trunk/java/doc/org/libjpegturbo/turbojpeg/TJ.html)中使用什么标志(上面的解压缩调用中的“0”),我都无法加载 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,或者在“解压缩”调用中有一个非常不明显的设置,我无法掌握。

      【讨论】:

        猜你喜欢
        • 2012-12-05
        • 1970-01-01
        • 2016-04-03
        • 2011-10-30
        • 1970-01-01
        • 2011-09-13
        • 2013-11-25
        • 2016-04-30
        • 2017-01-05
        相关资源
        最近更新 更多