Я ломал голову, пытаясь понять, что здесь делает библиотека Microsoft WIC / WCS, и был бы признателен за любую помощь от любого, кто разбирается в Windows Color Management. Документация по этому API ужасна.
Я читаю JPEG со встроенным профилем ICC, используя OpenColourProfile, но Windows, похоже, неправильно анализирует встроенную информацию ICC для некоторых изображений. Для других работает нормально. Однако, несмотря на то, что мне не удается проанализировать информацию заголовка с помощью Windows API, я могу правильно отображать все изображения, это просто синтаксический анализ информации заголовка встроенного профиля ICC, который является ошибочным.
Не работает
Используя инструмент exif_tool для отображения информации заголовка профиля ICC для изображения, которое не работает из моего кода, exif_tool правильно возвращает:
Profile CMM Type : Adobe Systems Inc.
Profile Version : 2.1.0
Profile Class : Display Device Profile
Color Space Data : RGB
Profile Connection Space : XYZ
Profile Date Time : 2000:08:11 19:51:59
Profile File Signature : acsp
Primary Platform : Apple Computer Inc.
CMM Flags : Not Embedded, Independent
Device Manufacturer : none
Device Model :
Device Attributes : Reflective, Glossy, Positive, Color
Rendering Intent : Perceptual
Connection Space Illuminant : 0.9642 1 0.82491
Profile Creator : Adobe Systems Inc.
Profile ID : 0
Profile Copyright : Copyright 2000 Adobe Systems Incorporated
Profile Description : Adobe RGB (1998)
Media White Point : 0.95045 1 1.08905
Media Black Point : 0 0 0
Red Tone Reproduction Curve : (Binary data 14 bytes, use -b option to extract)
Green Tone Reproduction Curve : (Binary data 14 bytes, use -b option to extract)
Blue Tone Reproduction Curve : (Binary data 14 bytes, use -b option to extract)
Red Matrix Column : 0.60974 0.31111 0.01947
Green Matrix Column : 0.20528 0.62567 0.06087
Blue Matrix Column : 0.14919 0.06322 0.74457
После прочтения заголовка профиля ICC в моем коде Windows возвращает тип CMM как 0000, который не определен (см. Ниже). Также тег версии анализируется на v2.0 (0x02000000), а не на v2.1, как показано в выходных данных exif_tool выше.
Кроме того, после этого запрос (в моем коде) на возврат тега ICC 0x64657363 (ProfileDescription) возвращает «opRGB» вместо «Adobe RGB (1998)».
Что касается данных EXIF для этого изображения, цветовое пространство определяется как «некалиброванное», и для него указан «индекс совместимости» со значением «R03», которое, как я понимаю, следует интерпретировать как Adobe RGB.
Работает
Используя другой JPG со встроенным профилем Adobe RGB (1998), я запустил его через exif_tool, и он отобразит:
Profile CMM Type : Adobe Systems Inc.
Profile Version : 2.1.0
Profile Class : Display Device Profile
Color Space Data : RGB
Profile Connection Space : XYZ
Profile Date Time : 1999:06:03 00:00:00
Profile File Signature : acsp
Primary Platform : Microsoft Corporation
CMM Flags : Not Embedded, Independent
Device Manufacturer : none
Device Model :
Device Attributes : Reflective, Glossy, Positive, Color
Rendering Intent : Media-Relative Colorimetric
Connection Space Illuminant : 0.9642 1 0.82491
Profile Creator : Adobe Systems Inc.
Profile ID : 0
Profile Copyright : Copyright (c) 1999 Adobe Systems Incorporated. All Rights Reserved.
Profile Description : Adobe RGB (1998)
Media White Point : 0.95045 1 1.08905
Media Black Point : 0 0 0
Red Tone Reproduction Curve : (Binary data 14 bytes, use -b option to extract)
Green Tone Reproduction Curve : (Binary data 14 bytes, use -b option to extract)
Blue Tone Reproduction Curve : (Binary data 14 bytes, use -b option to extract)
Red Matrix Column : 0.60974 0.31111 0.01947
Green Matrix Column : 0.20528 0.62567 0.06087
Blue Matrix Column : 0.14919 0.06322 0.74457
При использовании OpenColourProfile мой код (который использует Windows API) правильно анализирует информацию заголовка:
После этого запрос (в моем коде) на возврат тега ICC 0x64657363 (ProfileDescription) правильно возвращает «Adobe RGB (1998)».
Что касается данных EXIF для этого изображения, цветовое пространство определяется как «некалиброванное» и не указывается «индекс совместимости».
Код
/* COLOUR PROFILE MANAGEMENT */
IWICColorContext* pContextSrc = NULL;
IWICColorContext* pContextDst = NULL;
hr = factory->CreateColorContext(&pContextSrc);
if (!SUCCEEDED(hr))
return nullptr;
UINT numColourContexts = 0;
hr = wic->mFrame->GetColorContexts(1, &pContextSrc, &numColourContexts);
if (numColourContexts > 0)
{
hr = factory->CreateColorContext(&pContextDst);
if (!SUCCEEDED(hr))
return nullptr;
WCHAR destColourContextFilename[_MAX_PATH + 1];
DWORD destColourContextFilenameSize = sizeof(destColourContextFilename);
if (GetColorDirectory(NULL, destColourContextFilename, &destColourContextFilenameSize))
{
hr = StringCchCatW(destColourContextFilename,
sizeof(destColourContextFilename) / sizeof(destColourContextFilename[0]),
L"\\sRGB Color Space Profile.icm");
}
else
{
hr = E_UNEXPECTED;
}
if (SUCCEEDED(hr))
{
hr = pContextDst->InitializeFromFilename(destColourContextFilename);
}
if (SUCCEEDED(hr))
{
hr = factory->CreateColorTransformer(&wic->pColorTransform);
}
if (SUCCEEDED(hr))
{
hr = wic->pColorTransform->Initialize(wic->mFrame.get(),
pContextSrc,
pContextDst,
wic->mPixelFormat);
if (!SUCCEEDED(hr))
{
return nullptr;
}
}
// WICColorContextUninitialized = 0,
// WICColorContextProfile = 0x1,
// WICColorContextExifColorSpace = 0x2
WICColorContextType type;
pContextSrc->GetType(&type);
if (type == WICColorContextType::WICColorContextProfile)
{
UINT cbProfile = 0;
hr = pContextSrc->GetProfileBytes(0, NULL, &cbProfile);
if (!SUCCEEDED(hr))
return nullptr;
VOID* pvProfile = NULL;
if (SUCCEEDED(hr))
{
// allocate the block
pvProfile = HeapAlloc(
GetProcessHeap(),
HEAP_ZERO_MEMORY,
cbProfile);
hr = pvProfile ? S_OK : E_FAIL;
}
UINT cbSize = 0;
if (SUCCEEDED(hr))
{
// copy the profile into the block
hr = pContextSrc->GetProfileBytes(cbProfile, (BYTE*)pvProfile, &cbSize);
}
// ***Open the memory block as a HPROFILE***
HPROFILE hProfile = NULL;
// fill out a PROFILE structure
PROFILE prof =
{
PROFILE_MEMBUFFER,
pvProfile,
cbProfile
};
// create the HPROFILE
if (SUCCEEDED(hr))
{
/*hProfile = WcsOpenColorProfile(
&prof,
NULL,
NULL,
PROFILE_READ,
FILE_SHARE_READ,
OPEN_EXISTING,
0);*/
hProfile = OpenColorProfile(
&prof,
PROFILE_READ,
FILE_SHARE_READ,
OPEN_EXISTING);
hr = hProfile ? S_OK : E_FAIL;
HeapFree(GetProcessHeap(), 0, pvProfile);
}
PROFILEHEADER ph;
GetColorProfileHeader(hProfile, &ph);
DWORD size = 100;
CHAR description[100];
for (int i = 0; i < 100; i++)
{
description[i] = '\0';
}
BOOL b;
BOOL s = GetColorProfileElement(hProfile, 0x64657363, 12, &size, &description, &b);
string profileDescription = std::string(description);
Переменная ph представляет снимки экрана с синим изображением выше, а profileDescription представляет описание профиля ICC (которое работает для одного изображения, а не для другого).
Различия между заголовками ICC
Я суммировал различия в информации заголовка ICC, как сообщает exif_tool, что приводит к тому, что API Windows не может правильно проанализировать информацию встроенного заголовка ICC:
Работает
Profile Date Time : 2000:08:11 19:51:59
Primary Platform : Apple Computer Inc.
Rendering Intent : Perceptual
Profile Copyright : Copyright 2000 Adobe Systems Incorporated
Не работает
Profile Date Time : 1999:06:03 00:00:00
Primary Platform : Microsoft Corporation
Rendering Intent : Media-Relative Colorimetric
Profile Copyright : Copyright (c) 1999 Adobe Systems Incorporated. All Rights Reserved.
Другое программное обеспечение для редактирования изображений правильно отображает оба изображения как «Adobe RGB (1998)».
Кажется, что API Windows не любит, когда встроенная информация ICC предназначена для платформы Microsoft (?)
Это может быть вызвано отсутствием «Индекса совместимости» (указанного как «R03» для образа, который не работает, и не указан для образа, который действительно работает), но если бы это было так, это могло бы показаться ошибкой в Окна (?)
Может ли быть, что «Adobe RGB» и «Adobe RGB (1998)» - это два разных профиля, а все другое программное обеспечение, которое сообщает о них как «Adobe RGB (1998)», просто не различает их?
у меня голова болит ... Кто-нибудь знает, что здесь творится?
Ваше здоровье
РЕДАКТИРОВАТЬ:
Рабочее изображение (описание профиля = Adobe RGB (1998) при чтении с помощью Windows API):
Не работает (описание профиля = opRGB при чтении с помощью Windows API): < img src = "https://i.stack.imgur.com/gNaIW.jpg" alt = "введите описание изображения здесь">