GDI+白色背景的 JPG 的 DrawImage 不是白色的

发布于 2024-10-10 00:31:49 字数 1294 浏览 0 评论 0原文

我正在使用 GDI+ 在 C++ CWnd 窗口中显示 JPG。 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() );

在这里,我仅在图像的左侧有文本和一些混合(没有 Alpha,这是 JPG)。右边的一切都是纯白色的。你可以看到背景全是灰色的。

alt text

这里我开始删除内部内容(仅在左侧)。在某一点之后,整个背景开始显示白色。 ???

alt text

在开始显示白色之前删除图像区域的哪一部分并不重要,只要我删除其中的很大一部分。 png 也会发生同样的情况。

这是原始的 test.jpg 图像...

alt text

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.

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() );

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.

alt text

Here I started removing the internal content (only on the left side). After a certain point the entire background starts displaying white. ???

alt text

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.

Here is the original test.jpg image...

alt text

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

∞梦里开花 2024-10-17 00:31:49

我正在用我找到的解决方案回答我的问题。在我的例子中,直接在传递的 HDC 上使用graphics.DrawImage 似乎存在一些问题。如果我使用内存 DC 进行初始绘图,然后在 HDC 上进行 BitBlt,那么它就可以工作。

我在 PNG 和透明度方面也遇到了一些问题。使用下面的解决方案,我也能够解决这个问题。我的 PNG 是使用 Bitmap::FromStream 从流加载的。 Alpha 通道丢失,我尝试使用 LockBits 进行不同的尝试,并使用 PixelFormat32bppARGB 重新创建位图以及克隆。我能够得到一些东西来工作(经过大量的努力和额外的代码),但它仍然存在我在这里问的灰色背景问题。

就我而言,透明区域有一个已知的纯色背景色。我使用 Bitmap.GetHBITMAP 并传递背景颜色。然后首先在内存 DC 上绘制位图。在这里我能够解决我的两个问题!


  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 );

如果有人知道,我会感兴趣为什么这可以解决问题。

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.

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.

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.

塔塔猫 2024-10-17 00:31:49

你如何确认 JPG 背景是真正的白色? JPG 实现的压缩可以改变像素的颜色。如果存在混合颜色,则可能存在作为压缩一部分的某些类型的混合和混合。

你能给我们看看原图吗?

How did you confirm the JPG background is truly white? JPG implements compression that can vary the color of pixels. If there are mixed colors, then there can be certain types of blending and mixing that are part of that compression.

Can you show us the original image?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文