使用(MFC 的)CImage::SetPixel() 改变像素的颜色

Posted

技术标签:

【中文标题】使用(MFC 的)CImage::SetPixel() 改变像素的颜色【英文标题】:Changing the color of pixels using (MFC's) CImage::SetPixel() 【发布时间】:2020-11-06 18:12:10 【问题描述】:

我有一个带有 alpha(透明)层的 32 位 png 文件。我想使用 MFC 在每个像素的基础上更改 some 像素的颜色。性能不是问题(虽然更快更好)。

我编写代码调用CImage::GetPixel() 调整返回的COLORREFSetPixel() 新颜色,但整个图像是透明的。所以我写了下面的块,它只是获取和设置原始颜色。生成的图像是完全透明的。我还尝试简单地使用SetPixel(x, y, RGB(255, 0, 0)) 将所有像素设置为红色。有什么建议可以解决这个问题?

CImage image;
if(image.Load(sFilename) == S_OK)

    TRACE(L"IsTransparencySupported %d", image.IsTransparencySupported()); // Returns 1.
    TRACE(L"IsDIBSection %d", image.IsDIBSection()); // Returns 1.
    TRACE(L"Size %dx%d", image.GetWidth(), image.GetHeight()); // Displays 141x165.
    TRACE(L"BPP %d", image.GetBPP()); // Returns 32.
    TRACE(L"Pitch %d", image.GetPitch()); // Returns -564.

    COLORREF color;
    for(int x = 0; x < image.GetWidth(); x++)
    
        for(int y = 0; y < image.GetHeight(); y++)
        
            color = image.GetPixel(x, y); 
            image.SetPixel(x, y, color);
        
    

    if(image.Save(sFilenameNew, Gdiplus::ImageFormatPNG) != S_OK)
        TRACE(L"Error saving %s.", sFilenameNew);

else
    TRACE(L"Error loading png %s.", sFilename);

谢谢!

【问题讨论】:

COLORREF 宏似乎不支持 alpha,因此 alpha 始终为零。试试SetPixel(x, y, color | 0xff000000)。如果可行,您可能需要创建自己的宏来定义具有非零 alpha 的颜色常量。如果不行,可能是SetPixel太傻了,你可能要考虑在GetBits返回的缓冲区中设置像素 @pad COLORREF 完全能够代表 Alpha 通道。这是 GDI - 在大多数情况下 - 不准备支持 alpha 透明度。与GetPixel 一样,它不会(也不能更改为)返回alpha 透明度信息,因为它保留了0xFFFFFFFF (CLR_INVALID) 作为一个特殊的错误值。出于同样的原因,我不确定SetPixel 是否支持 alpha 透明度,尽管SetPixelV 可能。 【参考方案1】:
CImage image;
for (int i=0;i<image.ImgHeight;i++)

    for (int j=0;j<image.ImgWidth;j++)
    
        int index = i*image.ImgWidth+j;
        unsigned char* pucColor = reinterpret_cast<unsigned char *>      (image.GetPixelAddress(j , i)); 
        pucColor[0] = bValues[index];   
        pucColor[1] = gValues[index];   
        pucColor[2] = rValues[index];  
    

【讨论】:

以上是关于使用(MFC 的)CImage::SetPixel() 改变像素的颜色的主要内容,如果未能解决你的问题,请参考以下文章

(转载)DLL动态链接库编程入门之五:MFC扩展DLL

对使用共享 MFC 核心 DLL 的 MFC 项目使用 CTrace::SetLevel

mfc如何使用多线程搜索文件夹?

MFC 控件的使用

在共享DLL中使用MFC 和在静态库中使用MFC的区别

在mfc中如何使用按钮依次输入数据