将MFC Cimage初始化为纯色
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将MFC Cimage初始化为纯色相关的知识,希望对你有一定的参考价值。
我不使用c ++或MFC / ATL等,所以假设我什么都不知道。
整个画面是我需要接受带有透明层的PNG,并将其写成具有指定压缩的JPEG以传递给另一个系统。
我想知道的是,如何用纯白色初始化目标CImage结构?
到目前为止我已经这样做了(是的,我知道它有其他风格问题)
void ClipBoardFuncs::savePNGASJPEG(char filePath[256], char errorBuff[256]) {
int sizeOfErrorBuff = 256;
CImage imagePNG;
CImage imageJPG;
int xPNG, yPNG = 0;
imagePNG.Load(filePath);
xPNG = imagePNG.GetWidth();
yPNG = imagePNG.GetHeight();
//Create my target JPG same size and bit depth specifiying that there is no alpha channel (dwflag last param)
imageJPG.Create(xPNG, yPNG, imagePNG.GetBPP(), 0);
//Let there be white....
for (int x = 0; x <= xPNG; x++)
{
for (int y = 0; y <= yPNG; y++)
{
imageJPG.SetPixelRGB(x, y, 255, 255, 255);
}
}
//Copy the image over onto on the white
//BitBlt copies everything....
//imagePNG.BitBlt(imageJPG.GetDC(), 0, 0);
//Draw is more like the C# draw examples I've seen
imagePNG.Draw(imageJPG.GetDC(), 0, 0);
imageJPG.ReleaseDC();
HRESULT hr = NULL;
hr = imageJPG.Save(filePath, Gdiplus::ImageFormatJPEG);
imagePNG.Destroy();
imagePNG.ReleaseGDIPlus();
imageJPG.Destroy();
imageJPG.ReleaseGDIPlus();
LPCTSTR error = _com_error(hr).ErrorMessage();
strncpy_s(errorBuff, sizeOfErrorBuff, _com_error(hr).ErrorMessage(), _TRUNCATE);
}
可爱的C#人有这个答案:
Convert Transparent PNG to JPG with Non-Black Background Color
但是我需要将c ++ MFC解决方案用作DLL中的导出函数。
通过导出函数我的意思是你在kernel32.dll中找到的相同架构 - 抱歉,我不知道区分那种DLL与填充COM对象的术语。
任何人都可以建议一种更快的方法来将imageJPEG结构初始化为纯白色,而不是嵌套的x / y for循环吗?
干杯
4GLGuy
初始化可以使用Rectangle
或FillRect
完成(为此,FillRect
可能是首选 - Rectangle
绘制当前笔颜色的矩形轮廓,我们可能不需要)。
所以,序列看起来像这样:
CImage png;
png.Load(pDoc->filename);
CRect rect{ 0, 0, png.GetWidth(), png.GetHeight() };
CImage jpeg;
jpeg.Create(rect.Width(), rect.Height(), png.GetBPP());
auto dc = jpeg.GetDC();
HBRUSH white = CreateSolidBrush(RGB(255, 255, 255));
FillRect(dc, &rect, white);
png.Draw(dc, 0, 0);
jpeg.ReleaseDC();
jpeg.Save(L"Insert File name here", Gdiplus::ImageFormatJPEG);
jpeg.Destroy();
jpeg.ReleaseGDIPlus();
png.ReleaseGDIPlus();
GDI +足够“聪明”,当你使用具有alpha通道的图像执行.Draw
时,它会考虑该通道,而不必使用TransparentBlt
(或类似的东西)。
SetTransparentColor
不适用于你在这里尝试做的事情。 SetTransparentColor
用于没有alpha通道的图像(“透明层”)。然后,您可以使用它来选择将被视为透明的颜色 - 这当然有用,但不是您想要的。
您可以使用memset
,但仅适用于红色,绿色和蓝色通道都具有相同值(即黑色,白色或某些灰色阴影)的颜色。否则,您可以使用嵌套循环自行填充,但在大多数情况下,您可能希望使用FillRect
(它可能能够使用图形硬件进行加速,其中循环将非常可靠地在CPU上运行 - 最糟糕的情况是,它们的速度大致相同,但在某些情况下,FillRect
会更快。
imagePNG.Draw(imageJPG.GetDC(), 0, 0);
每次打电话给GetDC
都必须随后打电话给ReleaseDC
。另请参见CImage::GetDC
文档。
CImage::GetDC
提供了内存设备上下文的句柄。此句柄可用于使用标准GDI函数进行绘制。以后应该用CImage::ReleaseDC
清理手柄。
CImage::Draw
可能不知道透明颜色是什么。您必须使用TransparentBlt
告诉它透明颜色是什么。例如,要用白色替换红色:
HDC hdc = imageJPG.GetDC();
CDC dc;
dc.Attach(hdc);
CRect rc(0, 0, xPNG, yPNG);
dc.FillSolidRect(&rc, RGB(255, 255, 255));
dc.Detach();
imagePNG.TransparentBlt(hdc, rc, RGB(255, 0, 0));//replace red with white
imageJPG.ReleaseDC();
...
imageJPG.Save(...);
或者只是使用CImage::SetTransparentColor
:
imagePNG.SetTransparentColor(RGB(255, 0, 0));
imagePNG.Draw(hdc, rc);
for (int x = 0; x <= xPNG; x++){...}
要使用循环执行此操作,请将循环中的条件更改为x < xPNG
和x < yPNG
。
以上是关于将MFC Cimage初始化为纯色的主要内容,如果未能解决你的问题,请参考以下文章
VC++如何将rc资源中的图片加载到MFC的CImage对象中(附源码)
无法让CImage在Visual C ++ 2005(MFC)中工作