将 MFC 图像初始化为纯色
initialise an MFC Cimage to a solid colour
我不使用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#人有这样的答案:
将透明PNG转换为具有非黑色背景色的JPG
但我需要 c++ MFC 解决方案用作 DLL 中的导出函数。
通过导出函数,我的意思是与您在 kernel32 中找到的相同架构.dll - 抱歉,我不知道将这种 DLL 与填充 COM 对象的 DLL 区分开来的术语。
谁能建议一种比我这里有的嵌套 x/y for 循环更快的方法来将 imageJPEG 结构初始化为纯白色?
干杯
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
。
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 将 MFC 图像初始化为纯色
- 使用纯虚拟方法在C 中初始化抽象类
- 为什么可以内联初始化静态常量变量,而不能初始化纯静态(C++)
- 使用纯虚拟函数的实现初始化
- 是否应该初始化具有未重写的纯虚拟析构函数的类