Почему цвета GDI + меняются в зависимости от того, видна ли подсказка? - PullRequest
1 голос
/ 03 мая 2010

Я отображаю растровое изображение, используя GDI +. После загрузки растрового изображения из ресурса DLL я установил прозрачный цвет фона (синий - # 0000FF) с помощью TransparentBlt. В Windows Vista и более поздних версиях это работает должным образом.

Однако в системе Windows XP, которую мы тестируем, это работает, только когда отображается какая-либо подсказка (например, свойство title в IE или подсказка проводника Windows, отображаемая при наведении курсора мыши на файл и т. Д.). В остальное время цвет фона остается синим.

Кто-нибудь сталкивался с этим раньше или знает, как это остановить и как правильно сделать прозрачным синий?

Редактировать: После дальнейшего изучения я обнаружил, что установка глубины цвета в Windows XP на 16-битные цвета вместо 32-битных цветов заставляет TransparentBlt снова нормально работать. Очевидно, что это не идеальное решение, указывающее, какую глубину цвета следует использовать, но дает ли это какой-либо намек на то, что может происходить?

Edit2: пример кода включен.

m_pGDIBitmap = new Gdiplus::Bitmap(_Module.m_hInst, MAKEINTRESOURCE(lImageResource));
m_hMemDC = CreateCompatibleDC(hdc);

Gdiplus::Graphics myGraphics(m_hMemDC);

myGraphics.DrawImage(m_pGDIBitmap, 
    Gdiplus::Rect(0, 0, m_pGDIBitmap->GetWidth(), m_pGDIBitmap->GetHeight()), 
    0, 
    0,
    m_pGDIBitmap->GetWidth(), 
    m_pGDIBitmap->GetHeight(),
    Gdiplus::UnitPixel, &imAtt);

SetStretchBltMode(hdc, HALFTONE);
SetBrushOrgEx(hdc, rcBounds.left, rcBounds.top, NULL);
TransparentBlt(hdc, rcBounds.left, rcBounds.top, iScaledWidth, iScaledHeight, m_hMemDC, 0, 0, iBitmapWidth, iBitmapHeight, GetPixel(m_hMemDC, 0, 0));

Ответы [ 2 ]

1 голос
/ 13 мая 2010

То, что я закончил, было скорее обходным путем, но это сработало. Я изменил цвет фона на черный и добавил следующий код перед вызовом DrawImage:

Gdiplus::ImageAttributes imAtt;
imAtt.SetColorKey(Gdiplus::Color(0, 0, 0), Gdiplus::Color(0, 0, 0), Gdiplus::ColorAdjustTypeBitmap);

По какой-то причине использование этого с синим цветом, поскольку фон не работал, и использование TransparentBlt самостоятельно с любым цветом, не работало, но комбинация правильно применила прозрачность для различных операционных систем и глубины цвета, которые я пробовал.

Если бы у меня был доступ к программе рисования, которая поддерживала файлы растровых изображений с альфа-каналом, то есть 32-разрядные растровые изображения, я подозреваю, что сделать фон явным образом прозрачным, а затем использовать AlphaBlend, тоже бы сработало, но у меня не было возможности попробуйте это в то время.

1 голос
/ 03 мая 2010

Вы должны показать пример кода - код, который загружает растровое изображение, и код, который его отображает.

Исходя из описанных вами симптомов, я предполагаю, что вы загружаете растровое изображение не в собственном формате, а в текущем формате отображения. Это означает, что когда битовая глубина битовой карты отличается от битовой глубины дисплея, выполняется автоматическое преобразование цветового пространства. Когда это происходит, цвет, который вы предоставляете TransparentBlt, фактически отличается от цвета в растровом изображении.

Возможные альтернативные решения:

  1. Убедитесь, что растровое изображение загружено в его собственном формате без преобразования.

  2. Разрешить преобразование, но вместо предоставления жестко закодированного значения цвета для TransparentBlt, создайте GetPixel из известного "прозрачного" пикселя растрового изображения (например, слева вверху) и предоставьте это значение TransparentBlt.

...