使用GDI+在MFC中显示PNG图像

在为Sony公司进行的项目开发中,面临着创建一个现代且外观精美的应用程序的挑战。通常情况下,会设计一些图形并将其集成到应用程序中。主要使用PNG图像,因为它们支持透明背景,这可以创建一个更加精致和专业的用户界面外观。然而,在MFC中显示带有透明度的PNG图像可能会遇到一些挑战。虽然有文章介绍了如何在MFC按钮中使用PNG图像,但没有找到能够同时显示PNG图像并保持其透明度的Picture或Static控件。因此,开发了一个名为SG_PNGView的自定义控件,它通过允许开发者在MFC对话框中轻松显示带有透明度的PNG图像来解决这个问题。

首先,让了解一些基本概念。GDI+(Graphics Device Interface Plus)是微软为渲染2D图形提供的强大的图形库。它提供了一套全面的函数和类,用于在Windows应用程序中创建、操作和显示图形图像和文本。GDI+在底层图形硬件和操作系统之上提供了一个高级抽象,使开发者能够轻松创建视觉上吸引人且交互性强的用户界面。

GDI+非常适合使用诸如笔、画刷、字体、图像和路径等图形对象,通过相应的类允许开发者执行各种操作,如绘制线条、形状和文本,用颜色或渐变填充区域,转换图形对象,以及以不同格式处理图像。SG_PNGView使用GDI+在控件中加载和显示PNG图像。GDI+的Bitmap类被用来表示PNG图像,其方法被用来执行从资源加载图像、在绘制过程中将图像绘制到设备上下文,以及在图像加载过程中处理错误等操作。GDI+也被用于高效地操作和渲染图像的功能,确保在SG_PNGView控件中输出平滑且高质量的图形。在开发过程中,定义了静态控件的尺寸类型设置为垂直,以便实时查看图像是如何被拉伸的。

GDI+是开发者在Windows应用程序中创建丰富且视觉上吸引人的图形用户界面的多功能且必不可少的工具,它为处理2D图形提供了广泛的功能,使用起来既方便又高效。

魔法发生的地方

首先,会调用SetPNGImage()函数,它将PNG资源与静态控件关联起来。当调用该函数时,它会从指定的资源ID加载PNG图像,并用加载的图像初始化控件。

Status SG_PNGView::SetPNGImage(UINT nIDResource) { // 获取应用程序的实例句柄 HINSTANCE hInstance = AfxGetInstanceHandle(); // 在应用程序的可执行文件中查找指定的资源 HRSRC hResource = ::FindResource(hInstance, MAKEINTRESOURCE(nIDResource), _T("PNG")); if (!hResource) { return GenericError; // 资源未找到 } // 获取资源的大小 DWORD imageSize = ::SizeofResource(hInstance, hResource); // 获取指向资源数据的指针 const void * pResourceData = ::LockResource(::LoadResource(hInstance, hResource)); if (!pResourceData) { return OutOfMemory; // 锁定资源失败 } // 为资源数据分配全局内存 HGLOBAL hBuffer = ::GlobalAlloc(GMEM_MOVEABLE, imageSize); if (!hBuffer) { return OutOfMemory; // 内存分配失败 } // 锁定分配的内存,并将资源数据复制到其中 void * pBuffer = ::GlobalLock(hBuffer); if (!pBuffer) { ::GlobalFree(hBuffer); // 锁定内存失败,释放缓冲区 return OutOfMemory; } CopyMemory(pBuffer, pResourceData, imageSize); // 从分配的内存创建IStream对象 IStream* pStream = NULL; if (::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream) != S_OK) { ::GlobalUnlock(hBuffer); ::GlobalFree(hBuffer); return GenericError; // 创建流失败 } // 删除之前的位图(如果存在) delete m_pBitmap; // 从流创建GDI+ Bitmap对象 m_pBitmap = Bitmap::FromStream(pStream); // 释放IStream对象 pStream->Release(); // 解锁并释放分配的内存 ::GlobalUnlock(hBuffer); ::GlobalFree(hBuffer); // 检查位图是否成功创建 if (m_pBitmap == NULL) { return OutOfMemory; // 位图创建失败 } Status status = m_pBitmap->GetLastStatus(); if (status != Ok) { delete m_pBitmap; m_pBitmap = NULL; } return status; }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485