Краткая версия: есть ли простой способ узнать, является ли файл JPG CMYK или RGB в Delphi XE? Желательно без дополнительных библиотек ...

Более длинная версия: у меня есть сторонняя библиотека, которая принимает JPEG. Но по какой-то причине библиотеке необходимо знать, находятся ли они в цветовом пространстве CMYK или RGB. И что еще хуже, он отображает CMYK с неправильными цветами (возможно, что-то с CMS или около того ...). Сам Delphi (TJPEGImage) правильно отображает изображение CMYK, но кажется, что все «CMYK vs RGB» скрыто в разделе реализации jpeg.pas и не публикуется ...

Я искал много чего в Интернете, но здесь я нашел только сообщения нескольких лет назад. Также я нашел модифицированный файл jpeg.dcu Габриэля Корнеану, но все дело в том, чтобы Delphi правильно загружала изображение. И кажется, что XE правильно загружает CMYK JPEG.

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

P.S. Я хотел бы по возможности избегать добавления других библиотек в свой проект, и я хотел бы оставаться в рамках "стандартного Delphi", насколько это возможно, поэтому, если мне когда-либо понадобится перенести этот проект на Mac, iOS или Android, мне не нужно иметь дело с множеством внешних вещей ...

1
Radek Hladík 14 Сен 2014 в 15:03
Я изучал это и видел обнаружение CMYK, преобразование CMYK в RGB и т. д. Но, как я уже сказал, это скрыто в разделе реализации. Но модификация этого модуля может быть способом (просто раскрыть один из внутренних материалов), если нет другого лучшего решения.
 – 
Radek Hladík
14 Сен 2014 в 15:25
Модифицированный файл jpeg.dcu Габриэля Корнеану имеет свойство TJpegImage.IsCMYK. но я не уверен, подходит ли он для delphi-xe
 – 
kobik
14 Сен 2014 в 17:20
@kobik, его решение такое же простое (и несколько хрупкое), как Assigned(FBitmap) and (FBitmap.PixelFormat = pf32bit). Помощник класса прислушался, оф.
 – 
Free Consulting
14 Сен 2014 в 19:23
К сожалению, экспортированный PixelFormat в XE имеет только опции TJPEGPixelFormat = (jf24Bit, jf8Bit); И я бы очень хотел избежать использования предварительно скомпилированного DCU без исходного кода — и Габриэль Корнеану где-то упомянул, что он не выпускал исходный код, так как не знал, будет ли он в порядке с Embarcadero (поскольку он был основан на их исходном коде). ...
 – 
Radek Hladík
14 Сен 2014 в 19:56

2 ответа

Лучший ответ

Мы сузили количество решений до трех:

1
Radek Hladík 23 Сен 2014 в 16:25
См. измененную копию jpeg Андреотти в stackoverflow.com/questions/3143543/…. Просто поместите файлы в исходный код проекта. Компоновщик будет использовать их вместо файлов Codegear.
 – 
Rohit Gupta
10 Июн 2016 в 05:04

Простой способ, который, вероятно, будет работать почти всегда, - это поиск изображений маркера SOF (начало кадра).
Если этот маркер имеет 1 компонент, изображение в оттенках серого; если он состоит из 3 компонентов, скорее всего, это будет YCbCr; а если он состоит из 4 компонентов, скорее всего, это будет CMYK.

Если вам нужен более надежный метод, вам нужно будет определить формат файла JPEG. Для этого вы должны прочитать маркеры APPn. Оттуда обработка будет зависеть от типа найденного файла.

1
Jan Doggen 23 Сен 2014 в 16:39
Можно было бы - проанализировать файл JPEG до определенного уровня. Однако я понятия не имею, как выглядит JPEG внутри и как выглядит маркер SOF. Не говоря уже о подсчете его полей. Но если вы думаете, что это будет не так сложно, то я могу заглянуть в спецификацию формата JPEG... Печально то, что Delphi уже все это делает, я нашел точную строку в jpeg.pas, где информация подарок, и все, что мне нужно, это как-то его захватить :-)
 – 
Radek Hladík
15 Сен 2014 в 01:16
Есть пара хитростей, на которые стоит обратить внимание. Во-первых, некоторые форматы файлов JPEG позволяют встраивать миниатюру в маркер APPn. Всякий раз, когда вы сталкиваетесь с маркером APPn, вам нужно проверить размер и пропустить столько байтов, прежде чем возобновить сканирование. Следующий трюк заключается в том, что там есть 13 различных маркеров начала кадра (только 3 из которых вы, скорее всего, встретите). Однако количество компонентов в кадре имеет фиксированную структуру, одинаковую для всех маркеров SOFn. Помните, что длины закодированы бигендиальным кодом, поэтому для Intel вам нужно обратить их.
 – 
user3344003
15 Сен 2014 в 18:52