GDI+高级编程 - 图文(9)

2019-08-03 13:52

13.4.2 图像编解码与存储转换

保存和转换图像文件,需要使用编解码器的信息。

1.获取编解码器信息

可以用GDI+的全局函数来获取系统提供的图像编解码器信息:

// 获取编码器总数和存储编码器信息所需的空间大小(字节数): Status GetImageEncodersSize(UINT *numEncoders, UINT *size); // 获取编码器信息:

Status GetImageEncoders(UINT numEncoders, UINT size, ImageCodecInfo *encoders); // 获取解码器总数和存储解码器信息所需的空间大小(字节数): Status GetImageDecodersSize(UINT *numDecoders, UINT *size); // 获取解码器信息:

Status GetImageDecoders(UINT numDecoders, UINT size, ImageCodecInfo *decoders);

其中的编解码器信息类ImageCodecInfo中只含有一些数据成员,见表13-2。

表13-2 ImageCodecInfo类的数据成员 数据成员 Clsid FormatID CodecName DllName 类型 CLSID GUID 编解码器标识符 文件格式标识符 描述 WCHAR * 编解码器名称串 WCHAR * 包含编解码器的DLL文件的路径名串 FormatDescription WCHAR * 编解码器所使用的文件格式名串 FilenameExtension WCHAR * 包含所有关联文件扩展名串(分号分隔) MimeType Flags Version SigCount SigSize SigPattern SigMask

WCHAR * 包含编解码器的MIME类型串 DWORD DWORD DWORD DWORD BYTE * BYTE * ImageCodecFlags枚举的标志位组合 表示编解码器版本的整数 与编解码器关联的文件格式使用的签名数 表示每个签名的字节大小的整数 包含每个签名之模式的字节数组的指针 包含每个签名之掩模的字节数组的指针 41

其中MIME = Multipurpose Internet Mail Extension protocol, 多用途因特网邮件扩充协议。

例如(输出系统可用的编解码器信息,参见图13-32):

图13-32 系统可用图像编解码器信息

void CImgProcView::OnCodecInfo() {

Graphics graph(GetDC()->m_hDC); RedrawWindow();

SolidBrush brush(Color::Green); Font font(L\宋体\

UINT n, size;

ImageCodecInfo *codecInfos; GetImageEncodersSize(&n, &size);

codecInfos = (ImageCodecInfo *)malloc(size); GetImageEncoders(n, size, codecInfos);

CString str = L\编解码器名称\\t\\t格式描述\\t文件扩展名\graph.DrawString(str, str.GetLength(), &font,

PointF(10, 10), &brush);

for (UINT i = 0; i < n; i++) { }

42

str.Format(L\

codecInfos[i].FormatDescription, codecInfos[i].FilenameExtension);

graph.DrawString(str, str.GetLength(), &font,

PointF(10, 40 + 30 * REAL(i)), &brush);

}

free(codecInfos);

Image类也有两个方法,可以用来获取编码器的参数列表:

// 返回参数表的大小(字节数)

UINT GetEncoderParameterListSize(const CLSID *clsidEncoder); Status GetEncoderParameterList(const CLSID *clsidEncoder, UINT size,

EncoderParameters *buffer); // 获取参数表

其中的EncoderParameters类,只包含两个数据成员:

UINT Count; // 数组中EncoderParameter对象的数目

EncoderParameter Parameter[l]; // EncoderParameter对象的数组

其中的EncoderParameter类,包含如下4个数据成员:

GUID Guid; // 参数种类标识符

ULONG NumberOfValues; // 数组中Value数据成员指向值的数目 ULONG Type; // 确定参数的数据类型 VOID *Value; // 指向值数组的指针

2.图像的保存与转换

可以在对图像数据进行若干修改后,再保存到其他图像文件中(因为共享冲突,不能保存到原图像文件)。也可以将当前图像,用另一个指定的图像文件格式来保存(即格式转换)。这些都可以用下面的Image类方法Save来完成:

Status Save(const WCHAR *filename, const CLSID *clsidEncoder,

const EncoderParameters *encoderParams = NULL); Status Save(IStream *stream, const CLSID *clsidEncoder,

const EncoderParameters *encoderParams = NULL);

其中,需要CLSID(CLaSs, IDentifer,类标识符)的指针作为输入参数(比MFC中CImage类麻烦)。为此,可以自己编写一个由格式描述符来获取类ID的函数。

例如(作者自己写的,供大家参考):

bool CImgProcDoc::GetEncoderClassID(const wchar_t *format,

CLSID *pClsid) {

43

}

UINT n, size;

ImageCodecInfo *codecInfos; GetImageEncodersSize(&n, &size);

codecInfos = (ImageCodecInfo *)malloc(size); GetImageEncoders(n, size, codecInfos); for (UINT i = 0; i < n; i++)

if (wcscmp(codecInfos[i].FormatDescription, format) == 0){ }

*pClsid = codecInfos[i].Clsid; free(codecInfos); return true;

free(codecInfos); return false;

下面是作者自己写的一个保存图像为指定格式文件的消息响应函数,供大家参考。其中的fileName为CString类变量,是在图像文件被装入时,得到的当前图像文件名。这里用作默认的保存文件名。

void CImgProcDoc::OnFileSaveAs() {

if (ok) {

wchar_t filters[] = L\图像文件(*.bmp;*.gif;*.jpg;*.png;\\

*.tif;*.emf)| *.bmp;*.gif;*.jpg;*.png;*.tif;*.emf|位图文件\\ (*.bmp)|*.bmp|图形交换格式文件(*.gif)|*.gif|联合图象专家组[JPEG]文件\\ (*.jpg)|*.jpg|可移植网络图形文件(*.png)|*.png|标记图像文件格式[TIFF]\\ 文件(*.tif)|*.tif|增强型图元文件(*.emf)|*.emf|所有文件(*.*)|*.*||\

CFileDialog fileDlg(FALSE, NULL, fileName,

OFN_HIDEREADONLY, filters);

if (fileDlg.DoModal() == IDOK) {

CString extStr = fileDlg.GetFileExt(); extStr.MakeUpper();

if (extStr.Compare(L\

44

}

}

else if (extStr.Compare(L\== 0) extStr = L\CLSID clsid;

if (GetEncoderClassID(extStr, &clsid)) {

pImg->Save(fileDlg.GetPathName(), &clsid, NULL); if (pImg->GetLastStatus() != Ok)

MessageBox(NULL, L\保存文件出错!\错误\

} else

MessageBox(NULL, L\找不到指定的编码器!\错误\

说明:这里需要自己为文档类添加“另存为”菜单项ID_FILE_SAVE_AS的消息响应函数,还可以将“保存”菜单项的消息响应也定向于该函数。例如,可以在消息映射

ON_COMMAND(ID_FILE_SAVE_AS, &CImgProcDoc::OnFileSaveAs)

之后,手工添加消息映射:

ON_COMMAND(ID_FILE_SAVE, &CImgProcDoc::OnFileSaveAs)

13.4.3 位图类Bitmap

在三个主要的图像类中,Bitmap类对应于点阵位图,Metafile类对应于矢量图形,基类Image则对应于通用操作。

1.构造函数

Bitmap类有10个构造函数,其中常用的有:

Bitmap(const WCHAR *filename, BOOL useIcm = FALSE);

Bitmap(INT width, INT height, PixelFormat format = PixelFormat32bppARGB); Bitmap(INT width, INT height, Grpaphics *target);

其中PixelFormat可取值为表13-3中所列的常量。

表13-3 图像像素格式(14个)

常量 PixelFormat1bppIndexed

说明 每像素1位,索引色 45


GDI+高级编程 - 图文(9).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:中国铜管市场及投资调研报告目录

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: