CImage类的介绍与使用

程序代码下载处:http://download.csdn.net/source/2098910

下载处:http://hi.baidu.com/wangleitongxing/blog/item/9063b03e5e20f3c97c1e71c8.html

备注:这个程序是在xp系统,vs2008下做的,当初測试没出什么问题。

昨天(2014-11-11)我下了程序在win7以下測试,出现了评论里说的问题,解决方法我已经写在评论里面了。主要是由于路径的问题。大家參照着改动測下应该就没问题了。

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

}  

时间: 2024-08-10 19:09:46

CImage类的介绍与使用的相关文章

CImage类提供了GetBits()函数原理及实现

CImage类提供了GetBits()函数来读取数据区,GetBits()函数返回的是图片最后一行第一个像素的地址,网上有人说返回指针的起始位置是不同的,有些图片返回的是左上角像素的地址,有些是左下角像素的地址,跟图片内部顺序有关.GetPitch( ) 图像的间距. 如果返回值为负,位图是一个从下到上 DIB,并且原点是左下角. 如果返回值为正的,位图是一组 DIB,并且原点为左上角两个函数GetPitch()和GetHeight()一起使用就可以得到图片数据取得起始位置 img_Data=(

CImage类

https://www.baidu.com/link?url=NUpABnCOzr-DHBL225vaREsRcKSFhI1ejA9I67GNiHhnGNxXlKdkZfc9ghWFu7EnkK8wVa2ockJ8q-D47YF4zuzdzoldA9CxsSzV4kqrSgu&wd=&eqid=c5b9143800018ffc0000000359ba9114 http://blog.csdn.net/shuilan0066/article/details/7080244 前言       

CImage类使用

前言          CImage类是基于GDI+的,但是这里为什么要讲归于GDI? 主要是基于这样的考虑: 在GDI+环境中,我们可以直接使用GDI+ ,没多少必要再使用CImage类 但是,如果再GDI环境中,我们要想使用GDI+,有点麻烦,还得加入头文件,加入启动GDI+的代码和关闭GDI+的代码,显得太罗嗦了,GDI  的CBitmap 处理功能又有局限,只能处理BMP格式的图片. 怎么办?这时,我们便可使用CImage类,因为这个类本身封装了GDI+得使用环境,所以无需我们手动设置,

用CImage类来显示PNG、JPG等图片

CImage 是VC.NET中定义的一种MFC/ATL共享类,也是ATL的一种工具类,它提供增强型的(DDB和DIB)位图支持,可以装入.显示.转换和保存多种格式的图像文件,包括BMP.GIF.JPG.PNG.TIF等.CImage是一个独立的类,没有基类.(CImage类是基于GDI+的,从VC.NET起引进,VC 6.0中没有.)ATL (Active Template Library,活动模板库)是一套基于模板的 C++ 类,用以简化小而快的 COM 对象的编写.为了在MFC程序中使用CI

数字图像处理 CImage类的使用与封装(jpg png gif tif bmp等格式图像的加载、数据读写、保存等功能)

引入CImage类的原因 原有的CBitmap 类只能处理BMP格式的图片,非常受限.而CImage可以处理JPGE.GIF.BMP.PNG等多种格式图片,扩展了图片处理功能且能与CBitmap 进行转换( 因为所载入的位图句柄都是HBITMAP,所以可相互转换),因此引入CImage类进行图像处理. CImage类简介 CImage是MFC和ATL共享的新类,它能从外部磁盘中调入一个JPEG.GIF.BMP和PNG格式的图像文件加以显示,而且这些文件格式可以相互转换. CImage提供增强型的

设置定时任务(Timer类的介绍)

设置定时任务(Timer类的介绍) 在我们的许多项目中,我们都需要用到定时任务,因此想借此博文来对定时任务进行一个介绍. 设置定时任务步骤如下: 先new一个Timer对象 Timer timer = new Timer() ; 然后调用它的schedule方法,例如:timer.schedule(new Task(), 5 * 1000,5*1000); 相信上面的代码我们不会陌生,即使我们没有写过,但我们一定见到过. 要注意的是:上面第二步所提到的schedule方法有四个重载的方法.下面进

Tstrings类简单介绍及实例

用TStrings保存文件;var  S: TStrings;begin  S := TStringList.Create();  { ... }  S.SaveToFile('config.txt', TEncoding.UTF8); Tstrings类简单介绍及实例 在DELPHI的程序开发过程中Tstrings类的使用是比较频繁的,下面就此类在DELPHI5的开发环境中进行一下简单的介绍及实例(注:本文只对tstrings类中的方法及属性进行介绍, 从其父类继承的属性及方法不属本文讨论之内

【Entity Framework】初级篇--ObjectContext、ObjectQuery、ObjectStateEntry、ObjectStateManager类的介绍

本节,简单的介绍EF中的ObjectContext.ObjectQuery.ObjectStateEntry.ObjectStateManager这个几个比较重要的类,它们都位于System.Data.Entity.dll下的System.Data.Objects命名空间下.在后续的章节中,我们经常会用到它们的某些方法,以便完成我们的某些操作或目的.本节,简单的说明一下以后我们可能会用到的各个类的方法,以方便我们后续的学习. ObjectContext封装 .NET Framework 和数据库

供CImage类显示的半透明PNG文件处理方法

原文链接: http://blog.sina.com.cn/s/blog_4070692f010003gy.html 前补:没想到这个帖子好像挺多人看哪……看来大家都被这个png郁闷的够呛.显示png的代码其实很简单的,声明个CImage 变量,在初始化时候用.Load()读取外部的png图片,然后在OnPaint()里面用.Draw()来绘制就可以了. 我把源代码放到mofile了,内不含可执行文件,如果信得过我就请下载来看吧 :) http://pickup.mofile.com/04604