VC下图片加载.docx
- 文档编号:18218379
- 上传时间:2023-08-14
- 格式:DOCX
- 页数:17
- 大小:24.19KB
VC下图片加载.docx
《VC下图片加载.docx》由会员分享,可在线阅读,更多相关《VC下图片加载.docx(17页珍藏版)》请在冰点文库上搜索。
VC下图片加载
VC下加载JPG,JPEG,GIF,PNG图片最简单的方法
c/c++2010-08-1210:
47:
00阅读37评论0字号:
大中小订阅
VCMFC提供的APILoadBitmap/LoadImage类CBitmap等都只能操作BMP位图,图标。
对于其他常用的JPG/JPEG/GIF/PNG格式,它无能为力。
VC下怎样才能加载各种非BMP格式的图片呢?
下面介绍一种最简单的办法。
用CImage类的Load函数加载图片,之后用Detach取得HBITMAP句柄。
取得图片的HBITMAP句柄后就可以像操作BMP图片一样处理JPG/JPEG/GIF/PNG格式的图片了。
具体代码如下:
#include“atlimage.h”
CImageimg;
HRESULTret=img.Load(filename);//filename是要加载的文件名(包含路径)
HBITMAPbitmap=img.Detach();
//像操作BMP图片一样处理图片
给按钮加上bmp图片
Postedon2009-03-2518:
49无意乂阅读(1726)评论(0)编辑收藏
今天在Dialog中试了下给按钮加bmp图片.折腾了好久..
直接给CButton加图片的方法:
1.在资源编辑器中添加一个按钮.把它的Bitmap属性设为true
2.在按钮上点右键,添加一个变量m_Btn(CButton类型的)
3.将图片导入到资源管理器中.ID为IDB_BITMAP1
4.然后在初始化中加入如下代码:
HBITMAPhBmp=:
:
LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_BITMAP1));
m_Btn.SetBitmap(hBmp);
按钮上的文字就被图片取而代之了.但是按钮的四方边框仍然在.有点难看..
换成CBitmapButton就好看多了.没有那个四方边框.而且可以很容易地做出点动态的效果.方法如下:
1.在资源编辑器中添加一个按钮.
把它的OwnerDraw属性设为true.
把它的ID设为IDC_BUTTON1.
把它的Caption改成BITMAP_BUTTON
2.准备4张图片(只准备其中一两张也可以).添加到资源管理器中
正常状态时的按钮图片的ID设为"BITMAP_BUTTONU"
鼠标按下时的按钮图片的ID设为"BITMAP_BUTTOND"
鼠标点击过后的按钮图片的ID设为"BITMAP_BUTTONF"
按钮失效后的图片的ID设为"BITMAP_BUTTONS"
注意,一定要左右都带双引号!
其实就是"按钮的Caption+U或D或F或S"
3.在dlg的头文件里添加一个CBitmapButton类型的成员变量m_bbtn
4.在初始化中加入以下代码
m_bbtn.AutoLoad(IDC_BUTTON1,this);
VC下加载JPG/GIF/PNG图片的两种方法
仅管VC有提供相应的API和类来操作bmp位图、图标和(增强)元文件,但却不支持jpg、gif和png等格式的图片,而这几种格式却是常常要用到的。
这里我给大家介绍两种办法来操作这些格式的图片。
1.用APIOleLoadPicture来加载JPG、GIF格式的图片(注:
不支持PNG格式,另外GIF只能加载第一帧,且不支持透明)
OleLoadPicture函数实际上创建了一个IPicture类型的COM接口对象,然后我们可以通过这个COM接口来操作图片(实际上你也可以用APIOleCreatePictureIndirect来加载图片,不过相比而言OleLoadPicture函数简化了基于流的IPicture对象的创建),下面是示例代码:
(注:
由于只是用来示例,代码中省去了出错情况的处理)
/*
*如下代码段实现的功能是从指定的路径中读取图片,并显示出来
*/
voidDisplayImage(HDChDC,LPCTSTRszImagePath)
{
HANDLEhFile=CreateFile(szImagePath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);//从指定的路径szImagePath中读取文件句柄
DWORDdwFileSize=GetFileSize(hFile,NULL);//获得图片文件的大小,用来分配全局内存
HGLOBALhImageMemory=GlobalAlloc(GMEM_MOVEABLE,dwFileSize);//给图片分配全局内存
void*pImageMemory=GlobalLock(hImageMemory);//锁定内存
DWORDdwReadedSize;//保存实际读取的文件大小
ReadFile(hFile,pImageMemory,dwFileSize,&dwReadedSize,NULL);//读取图片到全局内存当中
GlobalUnlock(hImageMemory);//解锁内存
CloseHandle(hFile);//关闭文件句柄
IStream*pIStream;//创建一个IStream接口指针,用来保存图片流
IPicture*pIPicture;//创建一个IPicture接口指针,表示图片对象
CreateStreamOnHGlobal(hImageMemory,false,&pIStream)//用全局内存初使化IStream接口指针
OleLoadPicture(pIStream,0,false,IID_IPicture,(LPVOID*)&(pIPicture));//用OleLoadPicture获得IPicture接口指针
//得到IPictureCOM接口对象后,你就可以进行获得图片信息、显示图片等操作
OLE_XSIZE_HIMETRIChmWidth;
OLE_YSIZE_HIMETRIChmHeight;
pIPicture->get_Width(&hmWidth);//用接口方法获得图片的宽和高
pIPicture->get_Height(&hmHeight);
pIPicture->Render(hDC,0,0,100,100,0,hmHeight,hmWidth,-hmHeight,NULL);//在指定的DC上绘出图片
GlobalFree(hImageMemory);//释放全局内存
pIStream->Release();//释放pIStream
pIPicture->Release();//释放pIPicture
}
2.利用第三方的开发库来操作图片
这里我向大家推荐一个库CxImage。
CxImage里面包含了许多的类,可以用来加载、保存、显示和变换图片,而且支持许多的图片格式,包括BMP、JPEG、GIF、PNG、TIFF、MNG、ICO、PCX、TGA、WMF、WBMP、JBG、J2K等。
另外CxImage也支持Alpha通道,动画帧等许多功能,而且它还是开源免费的。
CxImage的当前的版本是v6.00,介绍和下载可以访问:
voidDisplayImage(HDChDC,CStringfileName)
{
CStringfileExt;//图片的扩展名
intlen=fileName.GetLength();
for(inti=len-1;i>=0;i--)//得到图片的扩展名
{
if(fileName[i]=='.')
{
fileExt=fileName.Mid(i+1);
break;
}
}
fileExt.MakeLower();//将扩展名转为小写
if(fileExt!
=_T(""))
{
//创建CxImage对象,其中静态方法CxImage:
:
GetTypeIdFromName用来根据扩展名获得图片格式的ID代表
CxImageimage(fileName,CxImage:
:
GetTypeIdFromName(fileExt));
if(image.IsValid())
{
image.Draw(hDC);
image.Destroy();
}
}
}
3提供一中更简单的方法
VCMFC提供的APILoadBitmap/LoadImage类CBitmap等都只能操作BMP位图,图标。
对于其他常用的JPG/JPEG/GIF/PNG格式,它无能为力。
VC下怎样才能加载各种非BMP格式的图片呢?
下面介绍一种最简单的办法。
用CImage类的Load函数加载图片,之后用Detach取得HBITMAP句柄。
取得图片的HBITMAP句柄后就可以像操作BMP图片一样处理JPG/JPEG/GIF/PNG格式的图片了。
具体代码如下:
#include“atlimage.h”
CImageimg;
HRESULTret=img.Load(filename);//filename是要加载的文件名(包含路径)
HBITMAPbitmap=img.Detach();
//像操作BMP图片一样处理图片
在VC中自建操作BMP位图文件的类
作者:
贾暾
西安万山软件有限公司
有编程经验的程序员都知道:
要使应用程序的界面美观不可避免的要使用大量位图。
现在流行的可视化编程工具对位图的使用提供了很好的支持,被称为三大可视化开发工具的VB、VC、Delphi通过封装位图对象对位图使用提供了很好的支持:
VB提供了两个功能很强的对象:
PictureBox及Image,通过使用它们,装载、显示位图变得非常容易。
Delphi中也提供了一个位图对象:
TImage,它的功能与用法与VB中的Image类似。
在VC中通过使用设备相关类CDC与GDI对象类CBitmap来完成位图的操作。
然而在VC中使用CBitmap类必须将BMP位图装入资源中,然后通过类CBitmap的成员函数使用它,在通过CDC类的成员函数操作它。
这样做有两点缺陷:
将位图装入资源导致可执行文件增大,不利于软件发行;只能使用资源中有限的位图,无法选取其它位图。
而且BMP位图文件是以DIB(设备无关位图)方式保存,BMP位图装入资源后被转换为DDB(设备相关位图),类CBitmap就是对一系列DDB操作的API函数进行了封装,使用起来有一定的局限性,不如DIB可以独立于平台特性。
要弥补使用资源位图的两点不足,就必须直接使用BMP位图文件。
VC的示例中提供了一种方法读取并显示BMP位图文件,但使用起来相当的麻烦。
首先使用API函数GlobalAlloc分配内存并创建HDIB位图句柄,所有操作只能直接读写内存,然后通过StrechDIBits及SetDIBsToDevice函数来显示于屏幕上,操作起来费时费力。
因此笔者通过研究类CBitmap的封装与DIB结构,使用Win32中提供的新函数,建立了一个专用于操作BMP文件的类,而且完全仿照类CBitmap的实现:
从类CGdiObject派生,新类的所有接口与类CBitmap的部分接口完全相同。
这样对于习惯使用CBitmap类接口用法的程序员来说两者的接口在使用上没有什么分别。
首先我们先简单介绍一下DIB的结构。
DIB位图既可以存在于内存,也可以以文件形式保存在磁盘上(BMP文件)。
所有DIB都包含两部分信息:
位图信息(BITMAPINFO),包括位图信息头和颜色表;位图数据。
对于内存中DIB的只要有上述两部分就行,而对于DIB文件则还要加上位图文件头。
两种结构如图所示:
DIBDIB文件
其次,Win32中提供了一个新函数CreateDIBSection,通过它可以创建一个存储DIB位的内存区域,既可以执行相应的GDI操作,又可以直接通过指向DIB位区域的指针方位DIB位区域。
这是一个非常有用的函数,通过它我们可以用DIB替代DDB。
在了解了相应的知识后,我们可以自己由类CGdiObject派生一个操作BMP文件的类:
CBitmapFile。
在自己编写类时有两点值得注意:
在BitmapFile.h文件中定义类CBitmapFile,首先必须声明类CBitmapFile是从类CGdiObject中公有派生。
然后在类中首先使用宏DECLARE_DYNAMIC(CBitmapFile)表明新类的最高父类是类CObject,是符合MFC的类库规范。
紧接着宏DECLARE_DYNAMIC的是声明静态函数FromHandle,这两个声明必须放在类定义的最前面。
在BitmapFile.cpp文件中类的成员函数的实现前加上IMPLEMENT_DYNAMIC(CBitmapFile,CGdiObject);表明类CBitmapFile直接派生于类CGdiObject。
在类CBitmapFile的声明中有三个函数与类Cbitmap中的定义稍有不同:
在类CbitmapFile中LoadBitmap函数的参数是LPCTSTR型,保存的是BMP文件的文件名。
在类CbitmapFile中CreateBitmap函数的参数中少了参数nPlanes,在函数内部默认为1。
在类CbitmapFile中CreateBitmapIndirect函数的参数中多了参数lpBits,它指向指定位图DIB位的内存区域。
在成员函数中最重要的是函数CreateBitmapIndirect和函数LoadBitmap:
在函数CreateBitmapIndirect中使用函数CreateDIBSection创建了一个以兼容DC为基础的HBITMAP句柄,并用继承自类CGdiObject的函数Attach把它与类CGdiObject的句柄m_hObject关联起来。
然后将指定位图的DIB位图数据拷贝到由函数CreateDIBSection创建的DIB位的内存区域。
在函数LoadBitmap中首先从指定文件名的文件中读取以结构BITMAPFILEHEADER为大小的数据块,然后由文件头标志判断文件是否为BMP位图文件,然后由BITMAPFILEHEADER中bfSize保存的文件大小与文件的真实大小比较文件是否有损坏,再由BITMAPFILEHEADER中bfOffBits与BITMAPFILEHEADER结构大小相减计算出位图信息头和颜色表一共的大小,动态申请一块空间保存位图信息头和颜色表信息,再由BITMAPFILEHEADER中bfSize与bfOffBits相减计算出DIB位图数据的大小,动态申请一块空间保存DIB位图数据,最后调用成员函数CreateBitmapIndirect来创建DIB位图。
在应用程序的OnPaint()事件中绘制DIB位图的方法与使用类CBitmap时绘制位图的方法完全相同,但有一点要注意的是由于CDC类没有提供返回新类CBitmapFile指针类型的将DIB位图选入内存的SelectObject函数,所以在使用SelectObject时要将返回类型强制转换为CbitmapFile*类型。
附源文件
//文件描述:
定义类CBitmapFile,此类是用于读取BMP文件,涉及读取、
//建立及一系列常用的操作。
//文件名:
BitmapFile.h
#ifndef_CBITMAPFILE_H_
#define_CBITMAPFILE_H_
classCBitmapFile:
publicCGdiObject
{
DECLARE_DYNAMIC(CBitmapFile)
public:
staticCBitmapFile*PASCALFromHandle(HBITMAPhBitmap);
//Constructors
CBitmapFile();
BOOLLoadBitmap(LPCTSTRlpszFileName);
BOOLCreateBitmap(intnWidth,intnHeight,UINTnBitCount,constvoid*lpBits);
BOOLCreateBitmapIndirect(LPBITMAPINFOlpBitmapInfo,constvoid*lpBits);
//Attributes
operatorHBITMAP()const;
intGetBitmap(BITMAP*pBitMap);
protected:
//Attributes
intGetColorNumber(WORDwBitCount);
public:
//Operations
DWORDSetBitmapBits(DWORDdwCount,constvoid*lpBits);
DWORDGetBitmapBits(DWORDdwCount,LPVOIDlpBits);
//Implementation
public:
virtual~CBitmapFile();
};
#endif
在VC6.0中使用GDI+的两种办法
GDI+是GDI的升级版本。
在VC6.0中并没有配备GDI+的相关文件。
那么如何在VC6.0使用GDI+呢?
我从网上搜索了一些资料,并结合自己的使用,总结出一下两种方法。
下面我各建一个MFC工程介绍这两种做法。
1.找到GDI+库文件和头文件,把它放到一个文件夹GDI+Files。
这个文件夹包括30个头文件和一个库文件。
2.新建一个单文档工程“UseGdiPlus”,把文件夹GDI+Files拷贝进工程文件夹。
3.进行工程设置,选择VC的Project菜单栏的Setting菜单项,在对话框中的C/C++选项卡中的Category一栏中选择General,在ProjectOptions中加入一个选择:
/I"GDI+Files",如下图所示:
在Project->stting->Link->Object/libary中加入GDI+Files\GdiPlus.lib,如下图所示:
4.新建一个.h文件QGdiPlus.h,该头文件的内容如下:
#pragmaonce
//AddGDI+supporttoMFCorWTLapplication.
//
//IncludethisfileinStdAfx.h
//
//MFC:
AddaQGdiPlusvariabletoyourapplicationclasstostartandstopGDI+.
//ATL:
CreateaQGdiPluslocalvariablein_tWinMain.
//Constructorstarts,destructorstops.
//EnsurethatGdiPlusheaderfilesworkproperlywithMFCDEBUG_NEWandSTLheaderfiles.
//Q317799:
PRB:
MicrosoftFoundationClassesDEBUG_NEWDoesNotWorkwithGDI+
#defineiterator_iterator
#ifdef_DEBUG
staticintnGdiPlusObjects=0;
namespaceGdiplus
{
namespaceDllExports
{
#include
};
#ifndef_GDIPLUSBASE_H
#define_GDIPLUSBASE_H
classGdiplusBase
{
public:
void(operatordelete)(void*in_pVoid)
{
nGdiPlusObjects--;
DllExports:
:
GdipFree(in_pVoid);
}
void*(operatornew)(size_tin_size)
{
nGdiPlusObjects++;
returnDllExports:
:
GdipAlloc(in_size);
}
void(operatordelete[])(void*in_pVoid)
{
nGdiPlusObjects--;
DllExports:
:
GdipFree(in_pVoid);
}
void*(operatornew[])(size_tin_size)
{
nGdiPlusObjects++;
returnDllExports:
:
GdipAlloc(in_size);
}
void*(operatornew)(size_tnSize,LPCSTR/*lpszFileName*/,int/*nLine*/)
{
nGdiPlusObjects++;
returnDllExports:
:
GdipAlloc(nSize);
}
voidoperatordelete(void*p,LPCSTR/*lpszFileName*/,int/*nLine*/)
{
nGdiPlusObjects--;
DllExports:
:
GdipFree(p);
}
};
#endif//#ifndef_GDIPLUSBASE_H
}
#endif//#ifdef_DEBUG
#defineULONG_PTRDWORD
#include
#ifdef_MFC_VER
#include
#endif
#undefiterator
usingnamespaceGdiplus;
#pragmacomment(lib,"Gdiplus.lib")
classQGdiPlus
{
public:
QGdiPlus():
m_Token(0){Gdiplus:
:
GdiplusStartupInputinput;Gdiplus:
:
GdiplusStartup(&m_Token,&input,NULL);}
~QGdiPlus()
{
Gdiplus:
:
GdiplusShutdown(m_Token);
#ifdef_DEBUG
#ifdef_MFC_
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VC 下图 加载