CImage 对话框初始化时候显示透明 PNG

使用CImage的时候,发现显示出来的并不是透明背景的图片,而是白色背景的图片。

后发现原因如下:

PNG图片的透明背景总是一片白色,后来才发现这其实是微软GDI+的设计问题,PNG图片是ARGB,使用GDI+载入图片的时候,GDI+会默认已经进行了预剩运算(PARGB),即每象素的实际值是已经和ALPHA值按比例相乘的结果,实际上它根本就没有做预乘,在使用透明图片的象素ALPHA通道的时候,CImage内部正是调用的AlphaBlend,没有预乘的图当作预乘的图片处理的结果就是这相当于一张和纯白背景进行了预剩,所以图象总是出现白色背景。

解决方法如下:

添加一个转换函数。

如下:

CImage img;  
HRESULT result = img.Load(_T("icon.png"));     
for(int i = 0; i < img.GetWidth(); i++)
{
    for(int j = 0; j < img.GetHeight(); j++)
    {
        unsigned char* pucColor = reinterpret_cast<unsigned char *>(img.GetPixelAddress(i , j));
        pucColor[0] = pucColor[0] * pucColor[3] / 255;
        pucColor[1] = pucColor[1] * pucColor[3] / 255;
        pucColor[2] = pucColor[2] * pucColor[3] / 255;
    }
}

在这里贴上自己项目里面的代码。我的工程要求对话框启动的时候自动加载透明PNG图。开始的时候把加载函数添加到OnInitDialog()里面,但发现没有任何效果,网上查了半天原因,发现画图的函数要添加到OnPaint()里面,修改之后,就生效了。

启动自动加载透明PNG图片的代码(位于OnPaint() 中,待画图的控件是一个ID为 IDC_V_H264_LOGO 的 Picture Control):

//画对话框不应该添加到OnInitDialog中,否则没有效果
	//应该添加到OnPaint中
	CRect rect;
	GetDlgItem(IDC_V_H264_LOGO)->GetClientRect(&rect);
	if(image.IsNull()==true)
	image.Load(".\\res\\264_ico.png");
	//转换函数?加上后背景为白色的PNG就变成了透明的------------
	//PNG图像自带Alpha通道,存储方式RGBA,代表了透明度,即pucColor[3]
	//当Alpha通道为0时,把RGB值都变成0
	for(int i = 0; i < image.GetWidth(); i++)
	{
		for(int j = 0; j < image.GetHeight(); j++)
		{
			unsigned char* pucColor = reinterpret_cast<unsigned char *>(image.GetPixelAddress(i , j));
			pucColor[0] = pucColor[0] * pucColor[3] / 255;
			pucColor[1] = pucColor[1] * pucColor[3] / 255;
			pucColor[2] = pucColor[2] * pucColor[3] / 255;
		}
	}
	//画一画
	image.Draw(GetDlgItem(IDC_V_H264_LOGO)->GetDC()->m_hDC,rect);

结果如下图所示:



转载于:https://www.cnblogs.com/leixiaohua1020/p/3902022.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将 BMP 图像转换为 PNG 格式并添加透明度,您可以使用 C++ 的第三方库,例如 libpng 和 zlib。以下是一个简单的示例代码,它使用这些库来执行所需的 BMP 到 PNG 转换和透明度添加: ``` #include <iostream> #include <fstream> #include <cstring> #include <png.h> #include "CImage.h" void write_png_file(char* file_name, int width, int height, png_bytep* row_pointers) { FILE* fp = fopen(file_name, "wb"); if (!fp) { std::cerr << "Error: Failed to open PNG file for writing\n"; return; } png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); if (!png_ptr) { std::cerr << "Error: Failed to create PNG write structure\n"; fclose(fp); return; } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { std::cerr << "Error: Failed to create PNG info structure\n"; png_destroy_write_struct(&png_ptr, nullptr); fclose(fp); return; } if (setjmp(png_jmpbuf(png_ptr))) { std::cerr << "Error: Failed to initialize PNG write\n"; png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return; } png_init_io(png_ptr, fp); if (setjmp(png_jmpbuf(png_ptr))) { std::cerr << "Error: Failed to write PNG image header\n"; png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return; } png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); if (setjmp(png_jmpbuf(png_ptr))) { std::cerr << "Error: Failed to write PNG image data\n"; png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return; } png_write_image(png_ptr, row_pointers); if (setjmp(png_jmpbuf(png_ptr))) { std::cerr << "Error: Failed to complete PNG write\n"; png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return; } png_write_end(png_ptr, nullptr); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); } void bmp_to_png_with_alpha(const char* bmp_file, const char* png_file) { CImage img; if (!img.Load(bmp_file)) { std::cerr << "Error: Failed to load BMP file\n"; return; } int width = img.GetWidth(); int height = img.GetHeight(); png_bytep* row_pointers = new png_bytep[height]; for (int y = 0; y < height; ++y) { row_pointers[y] = new png_byte[4 * width]; for (int x = 0; x < width; ++x) { COLORREF color = img.GetPixel(x, y); png_byte red = GetRValue(color); png_byte green = GetGValue(color); png_byte blue = GetBValue(color); png_byte alpha = (color != RGB(255, 0, 255)) ? 0xFF : 0x00; png_bytep pixel = &(row_pointers[y][4 * x]); pixel[0] = red; pixel[1] = green; pixel[2] = blue; pixel[3] = alpha; } } write_png_file(png_file, width, height, row_pointers); for (int y = 0; y < height; ++y) { delete[] row_pointers[y]; } delete[] row_pointers; } int main() { const char* bmp_file = "test.bmp"; const char* png_file = "test.png"; bmp_to_png_with_alpha(bmp_file, png_file); return 0; } ``` 在这个示例中,我们首先使用 CImage 类加载 BMP 图像文件。然后,我们遍历每个像素,并将其值转换为 PNG 格式,同时添加透明度(即,如果像素值为 RGB(255, 0, 255),则将其 alpha 值设置为 0,否则将其 alpha 值设置为 255)。最后,我们使用 write_png_file() 函数将转换后的 PNG 图像写入磁盘。 请注意,该示例仅提供了一个基本的转换功能。如果您需要处理大量图像或需要更高级的功能(例如,调整大小、旋转或滤镜等),则可能需要使用更强大的图像处理库,例如 OpenCV 或 ImageMagick。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值