CImage类的介绍与使用
CImage类的介绍与使用
程序代码下载处:http://download.csdn.net/source/2098910
下载处:http://hi.baidu.com/wangleitongxing/blog/item/9063b03e5e20f3c97c1e71c8.html
Visual C++的CBitmap类和静态图片控件的功能是比較弱的,它仅仅能显示出在资源中的图标、位图、光标以及图元文件的内容,而不像VB中的Image控件能够显示出绝大多数的外部图像文件(BMP、GIF、JPEG等)。因此,想要在对话框或其它窗体中显示外部图像文件则仅仅能借助于第三方提供的控件或代码。 如今,MFC和ATL共享的新类CImage为图像处理提供了很多对应的方法,这使得Visual C++在图像方面的缺憾一去不复返了。
CImage类概述
CImage是MFC和ATL共享的新类,它能从外部磁盘中调入一个JPEG、GIF、BMP和PNG格式的图像文件加以显示,并且这些文件格式能够相互转换。因为CImage在不同的Windows操作系统中其某些性能是不一样的,因此在使用时要特别注意。比如,CImage::PlgBlt和 CImage::MaskBlt仅仅能在 Windows NT 4.0 或更高版本号中使用,但不能执行在Windows 95/98 应用程序中。CImage::AlphaBlend和CImage::TransparentBlt也仅仅能在 Windows 2000/98或其更高版本号中使用。即使在Windows 2000执行程序还必须将stdafx.h文件里的WINVER和_WIN32_WINNT的提前定义改动成0x0500才干正常使用。
CImage封装了DIB(设备无关位图)的功能,因而可以让我们可以处理每一个位图像素。它具有下列最酷特性:
1、AlphaBlend支持像素级的颜色混合,从而实现透明和半透明的效果。
2、PlgBlt能使一个矩形区域的位图映射到一个平行四边形区域中,并且还可能使用位屏蔽操作。
3、TransparentBlt在目标区域中产生透明图像,SetTransparentColor用来设置某种颜色是透明色。
4、MaskBlt在目标区域中产生源位图与屏蔽位图合成的效果。
使用CImage的一般方法
使用CImage的一般方法是这种过程:
(1) 打开应用程序的stdafx.h文件加入�CImage类的包括文件:
#include<atlimage.h>
(2) 定义一个CImage类对象,然后调用CImage::Load方法装载一个外部图像文件。
(3) 调用CImage::Draw方法绘制图像。Draw方法具有例如以下定义:
程序代码:
BOOL Draw( HDC hDestDC, int xDest, int yDest,int nDestWidth, int nDestHeight, int xSrc, int ySrc,int nSrcWidth, int nSrcHeight );
BOOL Draw( HDC hDestDC, const RECT& rectDest, const RECT& rectSrc );
BOOL Draw( HDC hDestDC, int xDest, int yDest );
BOOL Draw( HDC hDestDC, const POINT& pointDest );
BOOL Draw( HDC hDestDC, int xDest, int yDest,int nDestWidth, int nDestHeight );
BOOL Draw( HDC hDestDC, const RECT& rectDest );
当中,hDestDC用来指定绘制的目标设备环境句柄,(xDest, yDest)和pointDest用来指定图像显示的位置,这个位置和源图像的左上角点相相应。
nDestWidth和nDestHeight分别指定图像要显示的高度和宽度,xSrc、ySrc、nSrcWidth和nSrcHeight用来指定要显示的源图像的某个部分所在的位置和大小。
rectDest和rectSrc分别用来指定目标设备环境上和源图像所要显示的某个部分的位置和大小。
须要说明的是,Draw方法综合了StretchBlt、TransparentBlt和AlphaBlend函数的功能。默认时,Draw的功能和 StretchBlt同样。但当图像含有透明色或Alpha通道时,它的功能又和TransparentBlt、AlphaBlend同样。因此,在普通情况下,我们都应该尽量调用CImage::Draw方法来绘制图像。
比如,以下的演示样例Ex_Image是实现这种功能:当选择"文件"ò"打开"菜单命令后,弹出一个文件打开对话框。当选定一个图像文件后,就会在窗体客户区中显示该图像文件内容。这个演示样例的详细过程例如以下:
(1) 创建一个默认的单文档程序项目Ex_Image。
(2) 打开stdafx.h文件里加入�CImage类的包括文件atlimage.h。
(3) 在view类中加入�成员变量CImage m_Image;
CEx_ImageView类加入�ID_FILE_OPEN的COMMAND事件映射程序,并加入�下列代码:
程序代码:
void CEx_ImageView::OnFileOpen() //Cyan:加入�
{
// TODO: 在此加入�命令处理程序代码
CString strFilter;
CSimpleArray<GUID>aguidFileTypes;
HRESULT hResult; //获取CImage支持的图像文件的过滤字符串
hResult=m_Image.GetExporterFilterString(strFilter,aguidFileTypes,_T("All Image Files"));
if(FAILED(hResult))
{
MessageBox(_T("GetExporterFilter调用失败!"));
return;
}
CFileDialog dlg(TRUE,NULL,NULL,OFN_FILEMUSTEXIST,strFilter);
if(IDOK!=dlg.DoModal())
return;
m_Image.Destroy();
//将外部图像文件装载到CImage对象中
hResult=m_Image.Load(dlg.GetFileName());
if(FAILED(hResult))
{
MessageBox(_T("调用图像文件失败!"));
return;
}
//设置主窗体标题栏内容
CString str;
str.LoadString(AFX_IDS_APP_TITLE);
AfxGetMainWnd()->SetWindowTextW(str+_T("-")+dlg.GetFileName());
Invalidate();//强制调用OnDraw函数
}
(4) 定位到CEx_ImageView::OnDraw函数处,加入�下列代码:
程序代码:
void CEx_ImageView::OnDraw(CDC* pDC)
{
CEx_ImageDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
//if (!pDoc)
//return;
// TODO: 在此处为本机数据加入�绘制代码
// Cyan:加入�
if(!m_Image.IsNull())
{
m_Image.Draw(pDC->m_hDC,0,0);
}
}
(5) 打开Ex_ImageView.h文件,加入�一个公共的成员数据m_Image:
程序代码:
public: CImage m_Image;(Cyan:我认为设置成私有成员比較好)
(6) 编译并执行。单击"打开"工具button,在弹出的对话框中指定一个图像文件后,单击"打开"button。
将图片用其他格式保存
CImage::Save方法能将一个图像文件按还有一种格式来保存,它的原型例如以下:
HRESULT Save( LPCTSTR pszFileName, REFGUID guidFileType= GUID_NULL);
当中,pszFileName用来指定一个文件名称,guidFileType用来指定要保存的图像文件格式,当为GUID_NULL时,其文件格式由文件的扩展名来决定,这也是该函数的默认值。它还能够是GUID_BMPFile(BMP文件格式)、GUID_PNGFile(PNG文件格式)、 GUID_JPEGFile(JPEG文件格式)和GUID_GIFFile(GIF文件格式)。
比如,以下的过程是在Ex_Image演示样例基础上进行的,我们在CEx_ImageView类加入�ID_FILE_SAVE_AS的COMMAND事件映射程序,并加入�下列代码:
程序代码:
void CEx_ImageView::OnFileSaveAs() //Cyan:加入�
{
// TODO: 在此加入�命令处理程序代码
if(m_Image.IsNull())
{
MessageBox(_T("请打开要另存的图像!"));
return;
}
CString strFilter;
strFilter="bmp位图文件|*.bmp|JPEG图像文件|*.jpg|GIF图像文件|*.gif|PNG图像文件|*.png||";
CFileDialog dlg(FALSE,NULL,NULL,NULL,strFilter);
if(IDOK!=dlg.DoModal())
return;
//假设没有指定文件扩展名,则为其加入�一个
CString strFileName,strExtension;
strFileName=dlg.m_ofn.lpstrFile;
if(dlg.m_ofn.nFileExtension==0)
{
switch(dlg.m_ofn.nFilterIndex)
{
case 1:
strExtension="bmp";
break;
case 2:
strExtension="jpg";
break;
case 3:
strExtension="gif";
break;
case 4:
strExtension="png";
break;
default:
break;
}
strFileName=strFileName+_T(".")+strExtension;
}
//图像保存
HRESULT hResult=m_Image.Save(strFileName);
if(FAILED(hResult))
{
MessageBox(_T("保存图像文件失败!"));
}
}
彩色图像转换成灰度图像
因为很多图像文件使用颜色表来发挥显示设备的色彩显示能力,因而将一张彩色图片变成黑色图片时须要调用CImage::IsIndexed来推断是否使用颜色表,若是则改动颜色表,否则直接将像素进行颜色设置。比如以下的代码:
程序代码:
void CEx_ImageView::OnToGray()//Cyan:加入�
{
// TODO: 在此加入�命令处理程序代码
if(m_Image.IsNull())
return;
if(!m_Image.IsIndexed())
{
//直接改动像素颜色
COLORREF pixel;
int maxY=m_Image.GetHeight();
int maxX=m_Image.GetWidth();
byte r,g,b,avg;
for(int x=0;x<maxX;x++)
{
for(int y=0;y<maxY;y++)
{
pixel=m_Image.GetPixel(x,y);
r=GetRValue(pixel);
g=GetGValue(pixel);
b=GetBValue(pixel);
avg=(int)(((int)r+g+b)/3);
m_Image.SetPixelRGB(x,y,avg,avg,avg);
}
}
}
else
{
//获取并改动颜色表
int maxColors=m_Image.GetMaxColorTableEntries();
RGBQUAD* lpColorTable;
lpColorTable=new RGBQUAD[maxColors];
m_Image.GetColorTable(0,maxColors,lpColorTable);
for(int i=0;i<maxColors;i++)
{
int avg=(lpColorTable[i].rgbRed+lpColorTable[i].rgbGreen+lpColorTable[i].rgbBlue)/3;
lpColorTable[i].rgbRed=avg;
lpColorTable[i].rgbGreen=avg;
lpColorTable[i].rgbBlue=avg;
}
m_Image.SetColorTable(0,maxColors,lpColorTable);
delete(lpColorTable);
}
Invalidate();//强制调用OnDraw
}
CImage类的介绍与使用的更多相关文章
- CImage类的使用介绍!
链接参考:http://www.cnblogs.com/juncheng/articles/1600730.html CImage是MFC和ATL共享的新类,它能从外部磁盘中调入一个JPEG.GIF. ...
- 用CImage类来显示PNG、JPG等图片
系统环境:Windows 7软件环境:Visual Studio 2008 SP1本次目的:实现VC单文档.对话框程序显示图片效果 CImage 是VC.NET中定义的一种MFC/ATL共享类,也是A ...
- GDI 总结三: CImage类使用
前言 CImage类是基于GDI+的.可是这里为什么要讲归于GDI? 主要是基于这种考虑: 在GDI+环境中,我们能够直接使用GDI+ ,没多少必要再使用CImage类 可是,假设再 ...
- CImage类
CImage封装了DIB(设备无关位图)的功能,因而可以让我们能够处理每个位图像素.这里介绍GDI+和CImage的一般使用方法和技巧. TAG: GDI CImage 后处理 我们知道,Vi ...
- CImage类提供了GetBits()函数原理及实现
CImage类提供了GetBits()函数来读取数据区,GetBits()函数返回的是图片最后一行第一个像素的地址,网上有人说返回指针的起始位置是不同的,有些图片返回的是左上角像素的地址,有些是左下角 ...
- c++ MFC图像处理CImage类常用操作代码
原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9598974.html MFC图像处理CImage类常用操作 CImage类头文件为#inclu ...
- 【VS开发】GDI+ 用CImage类来显示PNG、JPG等图片
系统环境:Windows 7 软件环境:Visual Studio 2008 SP1 本次目的:实现VC单文档.对话框程序显示图片效果 CImage 是VC.NET中定义的一种MFC/ATL共享类,也 ...
- 一个比CBitmap更优秀的类 -- CImage类
Visual C++的CBitmap类的功能是比较弱的,它只能显示出在资源中的图标.位图.光标以及图元文件的内容,而不像VB中的Image控件可以显示出绝大多数的外部图像文件(BMP.GIF.JPEG ...
- oc-12-NSString 类简单介绍及用法
// 11-[掌握]NSString 类简单介绍及用法 #import <Foundation/Foundation.h> int main(int argc, const char * ...
随机推荐
- hdoj 3065 病毒侵袭持续中(AC自动机)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3065 思路分析:问题需要模式匹配多个模式串,需要注意的是模式串会包含和重叠,需要对AC自动机的匹配过 ...
- poj 2375 Cow Ski Area bfs
这个题目用tarjan找联通块,缩点,然后统计出入度为0的点理论上是可行的,但问题是会暴栈.考虑到这个题目的特殊性,可以直接用一次bfs找到数字相同且联通的块,这就是一个联通块,然后缩点,统计出入度即 ...
- LeetCode 二叉树后序遍历(binary-tree-postorder-traversal)
Given a binary tree, return the postorder traversal of its nodes' values. For example:Given binary t ...
- MVCC 多版本并发控制
关于事务的介绍暂且不谈. InnoDB行级锁,虽然在很大程度上提高了事务的并发性,但是终究还是要耗费很大的.为了更进一步的提高并发性同时降低开销,存储引擎会同时实现MVCC. InnoDB实现MVCC ...
- Jsunpack
http://www.baidu.com/#wd=jsunpack&rsv_bp=0&tn=baidu&rsv_spt=3&ie=utf-8&rsv_sug3= ...
- Protel对话窗字体显示不完全问题解决办法(PCB)
点击protel99左上角的大箭头,点击preferences ,在对话框中把use client system fonts for all dialogs 复选框去掉,就可以了.
- oracle序列详解
tyle="margin:20px 0px 0px; font-size:14px; line-height:26px; font-family:Arial"> 序列: 是o ...
- python:利用asyncio进行快速抓取
web数据抓取是一个经常在python的讨论中出现的主题.有很多方法可以用来进行web数据抓取,然而其中好像并没有一个最好的办法.有一些如scrapy这样十分成熟的框架,更多的则是像mechanize ...
- MFC内部结构剖析
//////////////////////////////////////////////////////////////////////////////////////////MFC程序的执行顺序 ...
- C# 计算器 如果设置键盘输入的监听事件
这个事情困扰了我好久,之前java写的计算器程序可以正常运行了,但是因为打包问题(尝试过多次,感觉好麻烦,个人比较崇尚“点子”,注重创新,思来想去之后,决定试试C#模仿java再写一遍),想要用C#模 ...