Получение типа RGB: sRGB или AdobeRGB в С#?

Мне нужно проверить, является ли изображение sRGB или Adobe RGB в моем веб-приложении. Есть ли способ точно узнать, какой RGB имеет изображение?

ОБНОВЛЕНИЕ: пытался использовать Color.Context, но он всегда нулевой

код

Bitmap img = (Bitmap)image;
var imgPixel = img.GetPixel(0,0);
System.Windows.Media.Color colorOfPixel= System.Windows.Media.Color.FromArgb(imgPixel.A,imgPixel.R, imgPixel.G, imgPixel.B);
var context = colorOfPixel.ColorContext; //ColorContext is null

В System.Windows.Media также найдены PixelFormat и PixelFormats, которые могут показать, к какому именно типу RGB относится изображение. Но все же я не могу найти способ получить System.Windows.Media.PixelFormat img. Как мне это сделать?


person anindis    schedule 26.02.2015    source источник
comment
ColorContext это null, потому что вы создаете цвет синтетически, указывая компоненты. Чтобы использовать его, вам нужно использовать BitmapFrame, у которого есть свойство ColorContexts (вы найдете правильное в индексе 0). Я не могу прямо сейчас написать пример.   -  person Jcl    schedule 03.03.2015
comment
я сделал это BitmapSource bmp = new BitmapImage (uri); BitmapFrame bmf = BitmapFrame.Create(bmp); И ColorContexts имеют значение null (свойство Format всегда равно bgr32, хотя я конвертировал в sRGB и Adobe RGB с помощью онлайн-конвертера и проверял фотографии, которые босс дал мне в качестве примеров   -  person anindis    schedule 03.03.2015
comment
Использовал этот ответ. ColorContexts[0].colorspace всегда RGB: social.msdn.microsoft.com/Forums/vstudio/en-US/   -  person anindis    schedule 03.03.2015
comment
Я написал пример того, как получить цветовой контекст (а также протестировал его). Определение того, является ли этот контекст sRGB или AdobeRGB, может потребовать немного больше работы, чем   -  person Jcl    schedule 03.03.2015


Ответы (3)


Вам нужно будет использовать BitmapDecoder, чтобы получить кадр оттуда, а затем проверить контекст цвета:

BitmapDecoder bitmapDec = BitmapDecoder.Create(
   new Uri("mybitmap.jpg", UriKind.Relative),
   BitmapCreateOptions.None,
   BitmapCacheOption.Default);
BitmapFrame bmpFrame = bitmapDec.Frames[0];
ColorContext context = bmpFrame.ColorContexts[0];

После этого вам нужно будет обработать необработанный цветовой профиль (используя context.OpenProfileStream()), чтобы определить, какой это профиль.

Если вы хотите записать профили на диск, чтобы проверить их с помощью шестнадцатеричного редактора или чего-то еще, вы можете использовать этот код:

using(var fileStream = File.Create(@"myprofilename.icc"))
using (var st = context.OpenProfileStream())
{
  st.CopyTo(fileStream);
  fileStream.Flush(true);
  fileStream.Close();
}

Используя этот метод, я извлек необработанные данные из обоих цветов sRGB (ссылка). и AdobeRGB (ссылка), если вы хотите их проверить. В начале есть волшебные строки и идентификаторы, если вы хотите проверить, но я действительно не знаю их и не знаю, где найти таблицу для общих (встроенные профили могут быть бесконечными, не ограничиваясь AdobeRGB и sRGB).

Кроме того, одно изображение может иметь более одного цветового профиля.

С помощью этого метода, если ColorContexts пусто, то у изображения нет профиля.

person Jcl    schedule 03.03.2015
comment
Если исходное изображение имеет цветовой профиль, отличный от sRGB, необходимо использовать BitmapDecoder с параметрами BitmapCreateOptions.PreservePixelFormat и BitmapCacheOption.None, иначе преобразование цветов будет работать неправильно. - person The Conspiracy; 17.01.2016

Свойство Color.ColorContext MSDN: https://msdn.microsoft.com/en-us/library/System.Windows.Media.Color_properties(v=vs.110).aspx

person Arvind Sharma    schedule 26.02.2015

Вы можете использовать System.Drawing.Image.PropertyItems. Свойство «PropertyTagICCProfile» (Id=34675=0x8773) заполняется icc-профилем изображения, даже если оно встроено в данные изображения, а не в данные exif (или профиль не встроен, но изображение помечено как AdobeRGB). в exif: InteroperabilityIndex="R03").

byte[] iccProfile = null;
try {
    System.Drawing.Bitmap myImage = new Bitmap("Image.jpg");
    iccProfile = myImage.GetPropertyItem(34675).Value;
} catch (Exception) {
    //...
}
person ironed    schedule 20.11.2017