GDI + DrawImage JPG с белым фоном не белый - PullRequest
2 голосов
/ 04 января 2011

Я отображаю JPG в C ++ CWnd окне, используя GDI +. JPG имеет чисто белый фон, 0xffffff, но при отображении с использованием graphics.DrawImage, фон не совсем белый со смесью пикселей, таких как 0xfff7f7, 0xf7fff7, 0xf7f7f7. Ниже приведен код, я пробовал различные настройки, такие как CompositingMode, SmoothingMode и т. Д. Изображение не масштабируется.

Странно то, что цвет фона отличается в зависимости от другого небелого содержимого изображения. Если я сделаю простой полностью белый JPG, то он сработает, или даже в основном белый с черным текстом. Сравнение изображений показано ниже.


  CClientDC dc(this);
  Gdiplus::Graphics graphics(dc);

  Gdiplus::Bitmap* bmp = Gdiplus::Bitmap::FromFile( L"c:\\test.jpg" );
  graphics.SetInterpolationMode(Gdiplus::InterpolationModeHighQuality); 
  //graphics.SetCompositingQuality(Gdiplus::CompositingQualityHighQuality); 
  graphics.SetCompositingQuality(Gdiplus::CompositingQualityDefault); 
  graphics.SetCompositingMode(Gdiplus::CompositingModeSourceCopy); 
  //graphics.SetSmoothingMode( Gdiplus::SmoothingMode::SmoothingModeDefault );
  graphics.DrawImage(bmp, 0, 0, bmp->GetWidth(), bmp->GetHeight() );

Здесь у меня есть текст и немного смешения только на левой стороне изображения (без альфа, это JPG). Все справа чисто белое. Вы можете видеть, что фон весь серый.

alt text

Здесь я начал удалять внутренний контент (только с левой стороны). После определенного момента весь фон начинает отображаться белым. ???

alt text

На самом деле не имеет значения, какую часть области изображения я удаляю, прежде чем она начнет отображать белый цвет, пока я удаляю большую ее часть. То же самое происходит для PNG.

Вот оригинальное изображение test.jpg ...

alt text

Ответы [ 2 ]

3 голосов
/ 05 января 2011

Я отвечаю на мой вопрос найденным решением.Кажется, что использование graphics.DrawImage непосредственно на переданном HDC имеет некоторые проблемы в моем случае.Если я использую память DC для начального рисования, то BitBlt это на HDC, тогда он работает.

У меня также были некоторые проблемы с PNG и прозрачностью.Используя приведенное ниже решение, я смог решить и эту проблему.Мой PNG был загружен из потока с помощью Bitmap :: FromStream.Альфа-канал был потерян, и я пробовал разные попытки, используя LockBits и воссоздавая растровое изображение с PixelFormat32bppARGB, а также Cloning.Я смог заставить что-то работать (после долгих усилий и дополнительного кода), но у меня все еще была проблема с серым фоном, которую я задал здесь.

В моем случае у меня есть известный сплошной цвет фона дляпрозрачные области.Я использовал Bitmap.GetHBITMAP и передал цвет фона.Затем растровое изображение было сначала нарисовано в памяти DC.Здесь я смог решить обе мои проблемы!

<code>
  Gdiplus::Bitmap* bmp = Gdiplus::Bitmap::FromFile( L"c:\test.jpg" )
  Gdiplus::Color backColor( 0xff, 0xff, 0xff );
  HBITMAP hBmp;
  bmp->GetHBITMAP( backColor, &hBmp );
  CDC     bitmapDC;
  bitmapDC.CreateCompatibleDC(hdc);  // pass original HDC for drawing
  HBITMAP oldBmp = bitmapDC.SelectBitmap(hBitmap);
  ::BitBlt( hdc, x, y, cx, cy, bitmapDC.m_hDC, 0, 0, SRCCOPY );
  bitmapDC.SelectBitmap(oldBmp);
  DeleteObject( hBmp );

Если кто-нибудь знает, мне было бы интересно, почему это решает проблему.

0 голосов
/ 04 января 2011

Как вы убедились, что фон JPG действительно белый?JPG реализует сжатие, которое может варьировать цвет пикселей.Если есть смешанные цвета, то могут быть определенные типы смешивания и смешивания, которые являются частью этого сжатия.

Можете ли вы показать нам исходное изображение?

...