Чистая Java альтернатива JAI ImageIO для обнаружения изображений CMYK - PullRequest
12 голосов
/ 26 июля 2011

сначала я хотел бы объяснить ситуацию / требования, которые приводят к вопросу:

В нашем веб-приложении мы не можем поддерживать изображения CMYK (JPEG), поскольку IE 8 и ниже не могут отображать их,Таким образом, нам нужно определить, когда кто-то хочет загрузить такое изображение, и отрицать его.

К сожалению, ImageIO Java не будет читать эти изображения или не позволит мне получить обнаруженное цветовое пространство.После отладки кажется, что JPEGImageReader внутренне получает код цветового пространства 11 (что будет означать JCS_YCCK), но я не могу безопасно получить доступ к этой информации.

При запросе читателя на типы изображений я ничего не получаюдля CMYK, поэтому я мог бы принять no image types = unsupported image.

Я преобразовал исходное изображение CMYK в RGB, используя инструмент обработки изображений, чтобы проверить, будет ли оно доступно для чтения (я пытался смоделировать действия администратора при получении сообщения «CMYK не поддерживается»).Однако JPEGImageReader не будет читать это изображение, поскольку предполагает (комментарий в источнике!) 3-компонентное цветовое пространство RGB, но заголовок изображения сообщает о 4 компонентах (возможно, RGBA или ARGB) и, таким образом, IllegalArgumentException брошен.

Таким образом, ImageIO не вариант, так как я не могу надежно получить цветовое пространство изображения, и я не могу сказать администратору, почему в противном случае хорошее изображение (оно может быть отображено с помощьюбраузер) не будет принято из-за внутренней ошибки.

Это заставило меня попробовать JAI ImageIO, чья CLibJPEGImageReader отлично работает и правильно читает все мои тестовые изображения.

Однако, поскольку мы развертываем наше приложение в JBoss, который может содержатьа также в других приложениях, мы хотели бы сохранить их как можно более изолированными.AFAIK, мне нужно было бы установить JAI ImageIO на JRE или иным образом сделать нативные библиотеки доступными для их использования, и, таким образом, другие приложения также могут получить к ним доступ, что может вызвать побочные эффекты (по крайней мере, у насмного тестировать, чтобы убедиться, что это не так).

Это объяснение вопроса, и здесь он снова возникает: Существует ли чистая альтернатива Java JAI ImageIO на Java, которая надежно обнаруживает и, возможно, конвертирует CMYKизображения?

Заранее спасибо,

Томас

Ответы [ 4 ]

10 голосов
/ 01 августа 2011

Я нашел решение, которое подходит для наших нужд: Apache Commons Sanselan .Эта библиотека довольно быстро и точно читает заголовки JPEG (по крайней мере, все мои тестовые изображения), а также ряд других форматов изображений.

Недостатком является то, что она не будет читать данные изображений JPEG, но я могу сделатьчто с базовыми инструментами JRE.

Чтение изображений JPEG для преобразования довольно просто (те, которые ImageIO тоже отказывается читать):

JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(new FileInputStream( new File(pFilename) ) );
BufferedImage sourceImg = decoder.decodeAsBufferedImage();

Тогда, если Санселан скажет мнеизображение на самом деле CMYK, я получаю растр исходного изображения и конвертирую себя:

for( /*each pixel in the raster, which is represented as int[4]*/ )
{  
   double k = pixel[3] / 255.0;

   double r = (255.0 - pixel[0])*k;
   double g = (255.0 - pixel[1])*k;
   double b = (255.0 - pixel[2])*k;
}

Это дает довольно хорошие результаты, когда изображения RGB не слишком яркие или темные.Однако я не уверен, почему умножение на k предотвращает просветление.JPEG на самом деле декодируется в нативном коде, и преобразование CMYK-> RGB Я получил состояния, отличающиеся от других, я просто попытался умножить, чтобы увидеть визуальный результат.будь благодарен.

4 голосов
/ 26 августа 2012

Я опубликовал чистое решение Java для чтения всех видов изображений JPEG и преобразования их в RGB.

Он основан на следующих фактах:

  • Хотя ImageIO не может читать изображения JPEG с CMYK в качестве буферизованного изображения, оно может считывать необработанные данные пикселей (растр).
  • Sanselan (или Apache Commons Imaging, как его сейчас называют) можно использовать для считывания деталей изображений CMYK.
  • Есть изображения с инвертированными значениями CMYK (старая ошибка Photoshop).
  • Есть изображения с YCCK вместо CMYK (могут быть легко преобразованы).
2 голосов
/ 10 января 2014

Остерегайтесь другого поста, так как Java 7 не позволяет напрямую использовать реализацию Sun без специальных параметров, как указано в import com.sun.image.codec.jpeg. *.

2 голосов
/ 26 июля 2011

В нашем веб-приложении мы не можем поддерживать изображения CMYK (JPEG), так как IE 8 и ниже не могут отображать их. Таким образом, мы должны определить, когда кто-то хочет загрузить такое изображение и отрицать его.

Я не согласен с вашим «Таким образом, мы должны определить, когда кто-то хочет загрузить такое изображение, и отрицать его» * ​​1006 *. Гораздо более удобной политикой было бы преобразовать его в нечто иное, чем CMYK.

Остальная часть вашего поста немного сбивает с толку в том, что касается того, что вы просите об обнаружении и конверсии, что является двумя разными вещами. Еще раз, я думаю, что преобразование изображения намного удобнее для пользователя.

Не нужно писать жирным шрифтом, кстати:

Существует ли какая-либо чистая Java-альтернатива JAI ImageIO, которая надежно обнаруживает и, возможно, конвертирует изображения CMYK?

Чистая Java Я не знаю, но ImageMagick прекрасно работает для преобразования изображений CMYK в RGB. Вызов ImageMagick на стороне сервера из Java действительно не сложен. Раньше я делал это вручную, вызывая внешний процесс, но в настоящее время существуют оболочки типа JMagick и im4java .

...