问题描述
我正在使用GDI +在C ++ CWnd窗口中显示JPG. JPG具有纯白色背景0xffffff,但使用graphics.DrawImage显示时,背景为白色,混合了像素颜色,例如0xfff7f7、0xf7fff7、0xf7f7f7.下面是代码,我尝试了各种设置,例如CompositingMode,SmoothingMode等.图像未缩放.
I am displaying a JPG in a C++ CWnd window using GDI+. The JPG has a pure white background, 0xffffff, but when displayed using graphics.DrawImage, the background is off-white with a mix of pixel colors such as 0xfff7f7, 0xf7fff7, 0xf7f7f7. Below is the code, I have tried various settings such as CompositingMode, SmoothingMode, etc. The image is not scaled.
奇怪的是,背景颜色根据图像中的其他非白色内容而有所不同.如果我制作一个简单的全白色JPG,那么它就可以工作,或者甚至是只带有一些黑色文本的大部分是白色.图像比较如下所示.
The weird thing is that the background color is different depending on other non-white content in the image. If I make a simple all white JPG, then it works, or even a mostly white with just some black text. Comparison of images are shown below.
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() );
在这里,我仅在图像的左侧具有文本和一些混合功能(没有Alpha,这是JPG).右边的一切都是纯白色的.您可以看到背景都是灰色的.
Here I have text and some blending only on the left side of the image (no alphas, this is JPG) . Everything to the right is pure white. You can see the background is all grey.
在这里,我开始删除内部内容(仅在左侧).在特定点之后,整个背景开始显示白色. ???
Here I started removing the internal content (only on the left side). After a certain point the entire background starts displaying white. ???
只要我删除了大部分图像,在开始显示白色之前删除图像区域的哪一部分都没有关系. png也是如此.
It doesn't really matter which part of the image area I remove before it starts displaying white, as long as I remove a large portion of it. The same occurs for pngs.
这是原始的test.jpg图片...
Here is the original test.jpg image...
推荐答案
我用找到的解决方案回答了我的问题.在我看来,直接在传递的HDC上使用graphics.DrawImage有一些问题.如果我在初始图形中使用内存DC,则在HDC上对其进行BitBlt处理,然后就可以使用了.
I am answering my question with the solution that I found. It seems that using graphics.DrawImage directly on the passed HDC has some issues in my case. If I use a memory DC for the initial drawing, then BitBlt it on the HDC, then it works.
我在PNG和透明度方面也遇到了一些问题.使用下面的解决方案,我也能够解决此问题.我的PNG是使用Bitmap :: FromStream从流中加载的. Alpha通道丢失了,我正在尝试使用LockBits进行其他尝试,并使用PixelFormat32bppARGB以及克隆来重新创建位图.经过一些努力和额外的代码,我终于可以工作了,但是仍然有我在这里问的灰色背景问题.
I also had some problems with PNG and transparency. Using the solution below, I was able to solve this problem as well. My PNG was loaded from a stream using Bitmap::FromStream. The alpha channel was lost and I was trying different attempts using LockBits and re-creating the bitmap with PixelFormat32bppARGB, as well as Cloning. I was able to get something to work (after a lot of effort and extra code), but it still had the grey background problem that I asked here.
就我而言,透明区域的背景色是已知的.我使用了Bitmap.GetHBITMAP并传递了背景色.然后先将位图绘制到内存DC上.在这里,我能够解决我的两个问题!
In my case, I have a known solid background color for the transparent areas. I used Bitmap.GetHBITMAP and passed the background color. The bitmap was then drawn on the memory DC first. Here I was able to solve both of my problems!
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 );
如果有人知道,我很想知道为什么这可以解决问题.
If anyone knows, I would be interested why this fixes the problem.
这篇关于具有白色背景的JPG的GDI + DrawImage不是白色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!