Ответ 1
Вы уже пробовали libjpeg-turbo? Предполагается, что он сможет декодировать RGBA, и для него уже есть оболочка Java.
Кажется, есть некоторые дебаты о том, являются ли JPEG с альфа-каналами действительными или нет. Ответ, который я всегда считал правильным, что в FAQ JPEG, который по существу "Нет". (Это повторяется в другом вопросе о переполнении стека.)
Тем не менее, Java JPEGImageWriter в библиотеке Sun ImageIO будет с удовольствием писать и читать изображения в оттенках серого и RGB с альфа-каналом, хотя практически нет приложений в Linux, которые я пробовал до сих пор, которые будут правильно загружать такие файлы JPEG. Это было сообщено в прошлом как ошибка, но ответ Sun - это это допустимые файлы:
Это не ошибка изображения ввода-вывода, а недостаток в других приложениях заявляет заявитель. IIO JPEGImageWriter способен записывать изображения с помощью цветная модель, которая содержит альфа-канал (упоминается в родной IJG исходный код как цветовые пространства "NIFTY", такие как RGBA, YCbCrA и т.д.), но многие приложения не знают об этих цветовых пространствах. Поэтому, хотя эти изображения написанные клиентом IIO JPEG, соответствуют спецификации JPEG (которая слеп к различным возможностям цветового пространства), некоторые приложения могут не распознавать цветовые пространства, содержащие альфа-канал, и может ошибка или сделать поврежденное изображение, как описывает заявитель.
Разработчики, желающие поддерживать совместимость с этими другими альфа-невнимательными приложения должны писать изображения, которые не содержат альфа-канал (например, TYPE_INT_RGB). Разработчики, которым нужна возможность писать/читать изображение содержащий альфа-канал в формате JPEG, может сделать это с помощью 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:
И здесь вы можете увидеть результаты попыток просмотра изображений в оттенках серого + альфа и RGB + альфа с различными бит программного обеспечения Linux, которые, я считаю, используют libjpeg
:
Итак, похоже, что цветовое пространство просто неверно истолковано в каждом случае. Единственными допустимыми значениями в 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
из libjpeg
, значения cinfo.jpeg_color_space
и cinfo.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
для загрузки таких файлов, скорее всего, будет одним из наиболее общих интересов.
Любые предложения будут высоко оценены.
Вы уже пробовали libjpeg-turbo? Предполагается, что он сможет декодировать RGBA, и для него уже есть оболочка Java.
Даже если вы сохраняете свои изображения в виде 4-канальных jpeg-изображений, стандартного способа я не знаю, как указать формат цвета в файле jpeg.
В стандарте JFIF предполагается YCbCr.
Я попытался запустить libjpeg-turbo на цветные изображения, которые имеют альфа-канал и которые были сохранены с помощью java ImageIO как jpeg.
Вот как я скомпилировал libjpeg-turbo для 64-разрядного Linux:
$ 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
Вот как я запускаю Фиджи с правильным пути библиотеки и pathpath, чтобы включить 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 script для чтения таких файлов 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 не может читать jpeg с альфой, сохраненным ImageIO, или есть очень неочевидная настройка в вызове "распаковать", который я не могу понять.