WTL IPicture Viewer:WTL BmpView 样本应用程序的更新






4.64/5 (5投票s)
WTL BmpView 样本应用程序的更新版本,

引言
本文介绍了 WTLIPicture
Viewer,它是 WTL BmpView
示例应用程序的更新版本。WTLIPicture
Viewer 使用 OLE Picture
对象的包装器,并支持多种图像类型,包括位图、光标、增强图元文件、图标、gif、jpeg 和 windows 图元文件。可以打开和缩放图像文件,从剪贴板复制或粘贴图像,以及预览和打印图像。
Picture
对象包装器包含在源文件 WTLIPicture.h 中,并提供了将 Picture
对象与像示例 WTLIPicture
Viewer 这样的图像查看器一起使用所需的所有代码。它包含 MFC 中 CPictureHolder
类的 WTL 移植和扩展,还包含支持多种剪贴板图像格式的类。此外,它还为大多数支持的图像格式提供了一组半标准的结构,类似于 BITMAPFILEHEADER
和 BITMAPINFOHEADER
。
关于 PNG 的说明
WTLIPicture
Viewer 不支持 PNG 图像,因为 IPicture
的出现早于 PNG。
Picture 对象
OLE Picture
对象为位图、图标和图元文件提供了语言无关的抽象。主要接口是 IPicture
和 IPictureDisp
。IPicture
接口允许调用者管理图片属性并在图形渲染中使用图片。IPictureDisp
接口派生自 IDispatch
,以便通过自动化访问图片的属性。
以下小节将解释 CPixT
模板提供的各种方法,以简化 Picture
对象的使用。成员变量 m_pPix
是一个 IPicture
指针。
创建方法
CreateEmpty()
是 CPixT
提供的用于初始化 Picture
对象的基本方法。所有其他 create
方法都调用它,并将指向已填写的 PICTDESC
结构(包含图片信息)的指针传递进去。
BOOL CreateEmpty(LPPICTDESC lpPictDesc = NULL, BOOL bOwn = FALSE)
{ // build the PICTDESC structure if not passed in
if (lpPictDesc == NULL)
{
PICTDESC pdesc;
pdesc.cbSizeofstruct = sizeof(pdesc);
pdesc.picType = PICTYPE_NONE;
lpPictDesc = &pdesc;
}
// create the IPicture object
return SUCCEEDED(::OleCreatePictureIndirect(lpPictDesc, IID_IPicture, bOwn,
(LPVOID*)&m_pPix)); }
CreateFromBitmap()
是一组三个方法,允许从位图资源、CBitmap
指针或位图句柄初始化 Picture
对象。以下代码显示了接受位图句柄、可选调色板以及一个指示是否将位图所有权转移给 Picture
对象的标志的版本。
BOOL CreateFromBitmap(HBITMAP hbm, HPALETTE hpal, BOOL bTransferOwnership)
{ PICTDESC pdesc;
pdesc.cbSizeofstruct = sizeof(pdesc);
pdesc.picType = PICTYPE_BITMAP;
pdesc.bmp.hbitmap = hbm;
pdesc.bmp.hpal = hpal;
return CreateEmpty(&pdesc, bTransferOwnership); }
CreateFromEnhancedMetafile()
支持从增强图元文件创建 Picture
对象。
CreateFromIcon()
提供的方法可以从图标资源或图标句柄创建 Picture
对象。它支持图标和光标图像。
CreateFromMetafile()
支持从 Windows 图元文件初始化 Picture
对象。
加载方法
这些方法提供了从文件和流等各种输入源加载 Picture
对象的机制。
LoadFromDispatch
从图像文件加载 Picture
对象并设置 IPictureDisp
接口。
BOOL LoadFromDispatch(LPTSTR szFilePath)
{ // create a variant for the file name
VARIANT varFileName;
varFileName.vt = VT_BSTR;
varFileName.bstrVal = CComBSTR(szFilePath);
LPDISPATCH lpDisp = NULL;
// load the picture object from the file
BOOL bResult = SUCCEEDED(::OleLoadPictureFile(varFileName, &lpDisp));
// initialize the dispatch interface
if (bResult) lpDisp->QueryInterface(IID_IPicture, (LPVOID*)&m_pPix);
return bResult; }
LoadFromFile()
使用标准文件 I/O 从图像文件加载 Picture
对象。
LoadFromIStream()
从 IStream
加载。
LoadFromISequentialStream()
使用 ISequentialStream
指针加载 Picture
对象,例如来自 OLE DB 提供程序的指针。
LoadFromPath()
从文件名或 URL 加载。这是加载图像的最简单方法,但据说会泄漏资源。
BOOL LoadFromPath(LPCTSTR szFilePath)
{ return SUCCEEDED(::OleLoadPicturePath(CComBSTR(szFilePath), NULL, 0, 0,
IID_IPicture, (LPVOID *)&m_pPix)); }
保存方法
这些方法提供了将 Picture
对象保存到文件的机制。
SaveToDispatch()
使用 IPictureDisp
接口将 Picture
对象保存到图像文件。
BOOL SaveToDispatch(LPTSTR szFilePath)
{ BOOL bResult = FALSE;
LPPICTUREDISP pDisp = NULL;
if (SUCCEEDED(m_pPix->QueryInterface(IID_IPictureDisp, (LPVOID*)&pDisp)))
BOOL bResult = SUCCEEDED(::OleSavePictureFile((LPDISPATCH)pDisp,
CComBSTR(szFilePath)));
return bResult; }
SaveToFile()
使用标准文件 I/O 将 Picture
对象保存到图像文件。
渲染方法
将已创建或加载到 IPicture
中的图像绘制到设备上下文中。您可以传入一个小于图像尺寸的矩形以缩小,或传入一个大于图像尺寸的矩形以放大。
void Render(CDCHandle dc, const CRect& rcRender)
{ long hmWidth;
long hmHeight;
m_pPix->get_Width(&hmWidth);
m_pPix->get_Height(&hmHeight);
m_pPix->Render(dc, rcRender.left, rcRender.top, rcRender.Width(),
rcRender.Height(), 0, hmHeight-1, hmWidth, -hmHeight, NULL); }
属性
GetAttributes()
- 返回一个包含透明度和可缩放性标志的DWORD
GetDescription()
- 返回图像类型的文本描述GetHandle()
- 返回图像的OLE_HANDLE
GetHandle()
- 接收一个OLE_HANDLE
的引用并设置其值GetPixInformation()
- 返回一个包含图像信息(如大小、类型以及图像的前 256 字节)的结构GetSizeInHiMetric()
- 接收一个SIZE
引用并以HiMetric
返回高度和宽度GetSizeInPixels()
- 同上,但以Pixels
为单位GetType()
- 返回数字图像类型,例如PICTYPE_BITMAP
测试
这些方法返回一个 BOOL
值,指示 IPicture
包含的图像类型。
IsNull()
-m_pPix
为null
IsBitmap()
- 图像是位图、GIF 或 JPEGIsMetafile()
- 图像是 Windows 图元文件IsIcon()
- 图像是图标或光标IsEnhMetafile()
- 图像是增强图元文件
剪贴板助手类
WTLIPicture.h 包含两个类,用于获取或设置剪贴板图像。CClipboardFormatDlg
是一个小型对话框,当剪贴板上有多种图像类型可用时,用于提示选择图像类型。它支持位图、增强图元文件和 Windows 图元文件。CWTLIPictureClipboard
为位图、图标(转换为位图)以及两种图元文件类型提供 **复制** 功能。它还为位图和两种类型的图元文件提供 **粘贴** 功能。
半标准结构
WTLIPicture.h 提供了一组半标准的结构,类似于 BITMAPFILEHEADER
和 BITMAPINFOHEADER
。为光标和图标、jpeg、增强和 Windows 图元文件提供了结构。这些结构的目的是提供对图像文件头中常用引用值的访问。例如,这是 Windows 图元文件的 METAFILEHEADER
定义。
//////////////////////////////////////////////////////////
/* METAFILEHEADER (22 bytes) placeable metafile header. */
/* Metafiles may also start with a METAINFOHEADER only */
/* or with a METAFILEPICT clipboard header (see below) */
//////////////////////////////////////////////////////////
#include < pshpack2.h >
typedef struct tagMETAFILEHEADER {
DWORD mfKey; // Magic number (always 0x9AC6CDD7)
WORD mfHandle; // Metafile HANDLE number (always 0)
WORD mfLeft; // Left coordinate in metafile units (twips)
WORD mfTop; // Top coordinate in metafile units
WORD mfRight; // Right coordinate in metafile units
WORD mfBottom; // Bottom coordinate in metafile units
WORD mfInch; // Number of metafile units per inch.
// Unscaled = 1440; 720 = 2:1; 2880 = 1:2; etc.
DWORD mfReserved; // Reserved (always 0)
WORD mfChecksum; // Checksum value for previous 10 WORDs
} METAFILEHEADER, FAR *LPMETAFILEHEADER;
#include < poppack.h >
包含文件 pshpack2.h 和 poppack.h 是必需的,以便对结构进行字节对齐,因为它不以四字节边界结束。
已知问题
- 不支持 PNG 图像,因为
IPicture
不支持 PNG - 复制到剪贴板并以 WMF 格式粘贴回的 EMF 图像未对齐
SaveToDispatch()
可能会导致系统崩溃,尤其是在处理大型图像(> 5 MB)时- 缩放图像滚动时可能会出现轻微闪烁
致谢
CWTLIPictureT
模板类是 Microsoft Foundation Class 库中 CPictureHolder
的 WTL 移植和扩展。WTLIPictureViewer
应用程序基于 Windows Template Library 随附的 BmpView
示例应用程序。
使用条款
本文提供的示例应用程序是免费的,但受限于原始 BmpView
示例应用程序和 CPictureHolder
的任何限制。WTLIPicture.h 中提供的源代码可免费用于任何目的,前提是遵守 CPOL 要求。
本软件按“现状”分发,不提供任何形式的担保。