VC++中图像处理类CBitmap的用法

VC++中图像处理类CBitmap的用法

class CBitmap : public CGdiObject
{
  DECLARE_DYNAMIC(CBitmap)

public:
  static CBitmap* PASCAL FromHandle(HBITMAP hBitmap);

// Constructors
  CBitmap();

  BOOL LoadBitmap(LPCTSTR lpszResourceName);
  BOOL LoadBitmap(UINT nIDResource);
  BOOL LoadOEMBitmap(UINT nIDBitmap); // for OBM_/OCR_/OIC_
#ifndef _AFX_NO_AFXCMN_SUPPORT
  BOOL LoadMappedBitmap(UINT nIDBitmap, UINT nFlags = 0,
    LPCOLORMAP lpColorMap = NULL, int nMapSize = 0);
#endif
  BOOL CreateBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitcount,
      const void* lpBits);
  BOOL CreateBitmapIndirect(LPBITMAP lpBitmap);
  BOOL CreateCompatibleBitmap(CDC* pDC, int nWidth, int nHeight);
  BOOL CreateDiscardableBitmap(CDC* pDC, int nWidth, int nHeight);

// Attributes
  operator HBITMAP() const;
  int GetBitmap(BITMAP* pBitMap);

// Operations
  DWORD SetBitmapBits(DWORD dwCount, const void* lpBits);
  DWORD GetBitmapBits(DWORD dwCount, LPVOID lpBits) const;
  CSize SetBitmapDimension(int nWidth, int nHeight);
  CSize GetBitmapDimension() const;

// Implementation
public:
  virtual ~CBitmap();
#ifdef _DEBUG
  virtual void Dump(CDumpContext& dc) const;
#endif
};

CGdiObject

class CGdiObject : public CObject
{
  DECLARE_DYNCREATE(CGdiObject)
public:

// Attributes
  HGDIOBJ m_hObject;         // must be first data member
  operator HGDIOBJ() const;
  HGDIOBJ GetSafeHandle() const;

  static CGdiObject* PASCAL FromHandle(HGDIOBJ hObject);
  static void PASCAL DeleteTempMap();
  BOOL Attach(HGDIOBJ hObject);
  HGDIOBJ Detach();

// Constructors
  CGdiObject(); // must Create a derived class object
  BOOL DeleteObject();

// Operations
#pragma push_macro("GetObject")
#undef GetObject
  int _AFX_FUNCNAME(GetObject)(int nCount, LPVOID lpObject) const;
  int GetObject(int nCount, LPVOID lpObject) const;
#pragma pop_macro("GetObject")
  UINT GetObjectType() const;
  BOOL CreateStockObject(int nIndex);
  BOOL UnrealizeObject();
  BOOL operator==(const CGdiObject& obj) const;
  BOOL operator!=(const CGdiObject& obj) const;

// Implementation
public:
  virtual ~CGdiObject();
#ifdef _DEBUG
  virtual void Dump(CDumpContext& dc) const;
  virtual void AssertValid() const;
#endif
};

1 装载已导入工程的位图资源

// 装载位图

  CBitmap bmp;
  bmp.LoadBitmap(IDB_BITMAP);

2 装载位图文件

为了能让CBitmap能够装载位图文件,必须调用API函数LoadImage

HANDLE LoadImage(
 HINSTANCE hinst,  // handle of the instance containing the image
 LPCTSTR lpszName, // name or identifier of image
 UINT uType,    // type of image
 int cxDesired,   // desired width
 int cyDesired,   // desired height
 UINT fuLoad    // load flags
);

装载: Example 1:

HBITMAP hBmp = (HBITMAP)LoadImage(NULL,
    m_fileName,
    IMAGE_BITMAP,
    0, 0,
    LR_LOADFROMFILE | LR_DEFAULTCOLOR | LR_DEFAULTSIZE);

Example 2:

HBITMAP  hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
    "BG.bmp",
    IMAGE_BITMAP,
    0,0,
    LR_LOADFROMFILE);

将装载后得到的HBITMAP资源句柄 与 CBitmap 对象 相连

if (hBmp != NULL) {
    CBitmap *pBmp = CBitmap::FromHandle(hBmp);
  }

CBitmap bmp;
  if (hBmp != NULL) {
    bmp.DeleteObject();
    bmp.Attach(hBmp);
  }

3 显示位图

CBitmap bmp;
  bmp.LoadBitmap(IDB_BITMAP1);

  BITMAP bm;
  bmp.GetBitmap(&bm);

  CDC dc;
  dc.CreateCompatibleDC(pDC);
  CBitmap*pOldBmp=(CBitmap *)dc.SelectObject(&bmp);

  pDC->BitBlt(0,0,bm.bmWidth,bm.bmHeight,&dc,0,0,SRCCOPY);
  pDC->SelectObject(pOldBmp);

  bmp.DeleteObject();
  bmp.LoadBitmap(IDB_BITMAP2);

4 删除资源

CBitmap bmp;
  bmp.LoadBitmap(IDB_BITMAP);

  CBitmap *pOld=pDC->SelectObject(&bmp);

  // 此时位图对象还在pDC中,因此不能马上删除
  // 而是先将位图从DC中选出 然后再删除
  pDC->SelectObject(pOld);
  bmp.DeleteObject();

5 CBitmap 析构

当CBitmap作为局部变量 在其退出作用范围后,会发生析构,这时候CBitmap会将其对应的位图资源(hBitmap )释放掉。

若想继续使用该位图资源hBitmap,则在退出作用范围前,应将位图资源hBitmap和CBitmap对象通过Detach()函数进行分离

代码如下:

HBITMAP  CMyClass::Load()
{
    CBitmap bmp;
    bmp.LoadBitmap(IDB_BITMAP);

// 通过Detach 将资源与对象分离,这样bmp析构后,资源仍存在 
    // 否则 ,bmp析构时,会将位图资源一起析构掉,这样出了局部范围外,就不可再使用这个位图资源了
    return bmp.Detach();
}

6 在仅获得HBITMAP资源句柄情况下,如何获得这个资源的BITMAP信息

BITMAP bm;
GetObject(hBitmap,sizeof(BITMAP),&bm);

7 在内存中开辟资源空间 将原图保存到内存中

//-------------------在内存中建立区域以存放所得位图-------------------
// hBitmapSrc 为 CBitmap中保存的矩形原图资源句柄
// hDC 句柄
// 在内存中开辟位图资源,用以保存原图
HBITMAP CopyHBitmap(HBITMAP hBitmapSrc,HDC hDC)
{

  BITMAP bm;
  HBITMAP hBitmapDst;
  HDC hdcSrc,hdcDst;

  GetObject(hBitmapSrc,sizeof(BITMAP),&bm);
  hBitmapDst=CreateCompatibleBitmap(hDC,bm.bmWidth,bm.bmHeight);

  hdcSrc=CreateCompatibleDC(hDC);
  hdcDst=CreateCompatibleDC(hDC);

  SelectObject(hdcSrc,hBitmapSrc);
  SelectObject(hdcDst,hBitmapDst);

  BitBlt(hdcDst,0,0,bm.bmWidth,bm.bmHeight,hdcSrc,0,0,SRCCOPY);

  DeleteDC(hdcSrc);
  DeleteDC(hdcDst);
  return hBitmapDst;

}

下面给大家一个具体实例:将CBitmap类中的图像保存到文件

// 使用下面的代码,可以把CBitmap类中的图像保存到图像文件中。支持格式:BMP、JPG、GIF和PNG。 

void SaveBitmap(CString strFilePath, CBitmap Bitmap)
{
   if ( Bitmap.m_hObject )
   {
      CImage imgTemp;   // CImage是MFC中的类。
      imgTemp.Attach(Bitmap.operator HBITMAP());
      imgTemp.Save(strFilePath);
   }
} 

// 注意文件路径名strFilePath必须包含后缀,即BMP、JPG、GIF或PNG中的一种。

最后附上CBitmap,HBitmap,Bitmap区别及联系

加载一位图,可以使用LoadImage:

HANDLE LoadImage(HINSTANCE hinst,LPCTSTR lpszName,UINT uType,int cxDesired,int CyDesired,UINT fuLoad);

LoadImage可以用来加载位图,图标和光标

加载时可以规定加载图的映射到内存的大小:

cxDesired:指定图标或光标的宽度,以像素为单位。如果此参数为零并且参数fuLoad值中LR_DEFAULTSIZE没有被使用,那么函数使用目前的资源宽度。

 cyDesired:指定图标或光标的高度,以像素为单位。如果此参数为零并且参数fuLoad值中LR_DEFAULTSIZE没有被使用,那么函数使用目前的资源高度。

LoadImage的返回值是相关资源的句柄。因为加载的是位图所以返回的句柄是HBITMAP型的(需要强制转换)。

延伸理解 HBITMAP/CBitmap/BITMAP:

HBITMAP是bitmap的指针,

msdn中如是:Handle to a bitmap.typedef HANDLE HBITMAP;

CBitmap是mfc中封装bitmap的类;

msdn中:

Encapsulates(囊括) a Windows graphics device interface (GDI) bitmap and provides member functions to manipulate(操作) the bitmap.

BITMAP是一个结构体,封装着bitmap的一些信息。定义了逻辑位图的高,宽,颜色格式和位值。

MSDN中如是:This structure defines the type, width, height, color format, and bit values of a bitmap.

三者之间的关系转换:

HBITMAP hBitmap;

CBitmap bitmap;

BITMAP bm;

//下面是三者之间的联系:

bitmap.Attach(hBitmap);//由HBITMAP 得到关联的CBitmap

bitmap.GetBitmap(&bm); // 由CBitmap 得到关联的BITMAP
hBitmap=(HBITMAP)bitmap.GetSafeHandle();//由CBitmap得到相关的HBITMAP

BITMAP结构具有如下形式:

typedef struct tagBITMAP
{
     int      bmType;
     int      bmWidth;//宽
     int      bmHeight;//高
     int      bmWidthBytes;
     BYTE     bmPlanes;
     BYTE     bmBitsPixel;
     LPVOID bmBits;
}  BITMAP;

延伸理解下Attach/Detach:

attach是把一个C++对象与一个WINDOWS对象关联,直到用detach则把关联去掉。 
  如果attach了以后没有detach,则C++对象销毁的时候WINDOWS对象跟着一起完蛋。 
  attach了以后,C++对象的指针和WINDOWS对象的HWND会有一个映射关系,其作用相当于你直接用一个C++对象去Create一个WINDOWS对象,例如   CEdit   edit;   edit.create(...) 
  并且此映射是永久的,知道此对象完蛋为止。 
  如果用类似GetDlgItem函数也可以返回一个指针,并可以强制转换。GetDlgItem会到映射表里找。 
  有2种映射表,一中是永久的,一种是临时的。 
  直接用C++对象创建的WINDOWS对象或者是通过attach的对象的映射关系都被放到永久表中,否则就在临时表中创建映射。 
  所以GetDlgItem不推荐你保存返回的指针,因为你很难保证你的WINDOWS对象跟C++对象的关联是否放在永久表中。 
  如果映射是放在临时表中,那么在空闲时间会被自动删除。 
  用attcah完全是为了方便用MFC类的成员函数去操纵WINDOWS对象。

(0)

相关推荐

  • VC实现图片拖拽及动画的实例

    基础知识 1.PictureBox控件的使用 2.加载位图文件 1.通过文件路径获得位图句柄 复制代码 代码如下: //获得位图句柄  void CMovePictureDlg::GetHandleFromPath(CString path)  {      hBitmap= (HBITMAP)::LoadImage(AfxGetInstanceHandle(),path,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE);//创建位图句柄

  • VC运用OPENGL加载BMP纹理图的实现方法汇总

    OpenGL是专业的图形程序接口,功能非常强大,调用方便的底层图形库.本文汇总了运用OPENGL加载BMP纹理图的几个实现方法. 方法一: 首先获取位图句柄: HBITMAP hBmp = (HBITMAP) ::LoadImage (AfxGetResourceHandle(),MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0, 0,LR_CREATEDIBSECTION); 然后根据位图句柄得到位图信息: BITMAP BM; ::GetObject

  • VC++基于Dx实现的截图程序示例代码

    本文所述的程序示例为VC++图象特效的截图示例,需要DirectX 3.0以上版,代码中的GetScreen函数是本截图程序的关键.运行这个程序可用Esc键结束.代码中需要ddutil.h与ddutil.cpp文件,请自行下载添加.关于InitDDraw()函数,功能是初始化DirectDraw环境,创建换页链(主页面,一个后台缓冲区),以及创建一个定时器. 具体的功能代码如下: #include <windows.h> #include <windowsx.h> #include

  • CISBitmap派生的VC++位图透明类实例

    本文所述为一个由CISBitmap派生的VC++位图透明类,可以方便实现BMP图像的透明处理,主要包含两个文件,使用时主需要将其引入到你的C++工程中即可,具体的类代码如下: CISBitmap.cpp文件代码如下: #include <stdafx.h> #include "CISBitmap.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW

  • VC++实现的OpenGL线性渐变色绘制操作示例

    本文实例讲述了VC++实现的OpenGL线性渐变色绘制操作.分享给大家供大家参考,具体如下: 用到的思路就是在应力的最大值和最小值之间划分区间,每个区间的标识点对应不同的颜色值. 然后在区间内的应力值对应的颜色就进行插值来计算. 代码如下: #include <GL/glut.h> #include <iostream> #include <cmath> using namespace std; const GLsizei width=640; const GLsize

  • 双缓冲解决VC++绘图时屏幕闪烁

    通常来说程序根据需要调用Invalidate(FALSE)使窗口客户区无效引起重绘,然后在窗口OnPaint函数(基于文档视图的程序则是OnDraw)中进行稳定绘图就行了.但是,我们在OnPaint中进行多重绘制(画背景.棋盘.棋子等),前后绘制的反差造成了闪烁现象.以前知道Java中解决屏幕闪烁问题是用双缓冲的方法,现在发现在vc++中也是可以这么做的.简单来说,双缓冲就是先把需要绘制的东西全部一口气画在内存中,最后把内存中的数据搬到屏幕上显示. 最近做中国象棋,绘制界面时遇到些问题,绘图过程

  • Cocos2d-x学习笔记之世界坐标系、本地坐标系、opengl坐标系、屏幕坐标系

    cocos2d-x的坐标系很重要,想要学好该引擎,深入理解它的坐标体系很重要.注释写的很清楚了,对照上运行结果一块来看代码吧! bool HelloWorld::init() { bool bRet = false; do { CC_BREAK_IF(! CCLayer::init()); //opengl的坐标系和世界坐标系相同,都是以屏幕左下角为原点,向右为x轴的增加方向,向上为y轴的增加方向 //这里的世界指的是游戏世界 //屏幕坐标系是以左上角为原点,是我们熟悉的 //本地坐标系也叫节点

  • VC++实现View内容保存为图片的方法

    本文实例讲述了VC++实现View内容保存为图片的方法.分享给大家供大家参考,具体如下: 我们在单文档应用程序中,经常需要将View中的内容保存为各种格式的图片文件,以便打印.乍一看,可能不知道从哪里下手,其实主要就是用到Bitmap的save方法,如: HDC hmemDC = ::CreateCompatibleDC( hdc ); HBITMAP hBmp = ::CreateCompatibleBitmap( hdc, destRect.Width(),destRect.Height()

  • VC++中图像处理类CBitmap的用法

    VC++中图像处理类CBitmap的用法 class CBitmap : public CGdiObject { DECLARE_DYNAMIC(CBitmap) public: static CBitmap* PASCAL FromHandle(HBITMAP hBitmap); // Constructors CBitmap(); BOOL LoadBitmap(LPCTSTR lpszResourceName); BOOL LoadBitmap(UINT nIDResource); BOO

  • Yii数据模型中rules类验证器用法分析

    本文实例讲述了Yii数据模型中rules类验证器用法.分享给大家供大家参考,具体如下: public function rules() { return array( array('project_id, type_id, status_id, owner_id, requester_id,', 'numerical', 'integerOnly'=>true), array('name', 'length', 'max'=>256), array('description', 'length

  • Java中BigDecimal类的简单用法

    本文实例讲述了Java中BigDecimal类的简单用法,是Java程序设计中非常实用的技巧,分享给大家供大家参考.具体用法分析如下: 一般来说,一提到Java里面的商业计算,我们都知道不能用float和double,因为他们无法进行精确计算.但是Java的设计者给编程人员提供了一个很有用的类BigDecimal,他可以完善float和double类无法进行精确计算的缺憾.BigDecimal类位于java.maths类包下.首先我们来看下如何构造一个BigDecimal对象.它的构造函数很多,

  • VC中删除类的两种操作方法

    本文实例讲述了VC中删除类的两种操作方法.分享给大家供大家参考.具体方法如下: 方法一: 应该是先在windows里面删除.h和.cpp文件,然后打开项目,Ctrl-W打开Class    wizard,选这个Dialog类,然后提示找不到了,选remove,然后到File    view列表里面选这两个文件,按Delete删除,这样才彻底,否则.clw文件内会保留信息的 方法二: 在你的工程的FileView中删除相应的h文件和cpp文件,然后把工程关了 到相应文件夹下,把该类的h和cpp文件

  • VC中CWinThread类以及和createthread API的区别分析

    本文实例讲述了VC中CWinThread类以及和createthread API的区别分析,分享给大家供大家参考.具体分析如下: CWinThread CObject  └CCmdTarget     └CWinThread CWinThread对象代表在一个应用程序内运行的线程.运行的主线程通常由CWinApp的派生类提供:CWinApp由CWinThread派生.另外,CWinThread对象允许一给定的应用程序拥有多个线程. CWinThread支持两种线程类型:工作者线程(Worker

  • 浅谈java中BigDecimal类的简单用法

    一.BigDecimal概述 ​ Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的数进行运算和处理.一般情况下,对于那些不需要准确计算精度的数字,我们可以直接使用Float和Double处理,但是Double.valueOf(String) 和Float.valueOf(String)会丢失精度.所以开发中,如果我们需要精确计算的结果,则必须使用

  • 详解Java中String类的各种用法

    目录 一.创建字符串 二.字符.字节与字符串的转换 1.字符与字符串的转换 2.字节与字符串的转换 三.字符串的比较 1.字符串常量池 2.字符串内容比较 四.字符串查找 五.字符串替换 六.字符串拆分 七.字符串截取 八.String类中其它的常用方法 九.StringBuffer 和 StringBuilder 1.StringBuilder与StringBuffer的区别 2.StringBuilder与StringBuffer常用的方法 十.对字符串引用的理解 一.创建字符串 创建字符串

  • java中Scanner类的简单用法分享

    复制代码 代码如下: public static void main(String[] args) {     System.out.println("请输入值,以回车结束:");     Scanner sc = new Scanner(System.in);     sc.useDelimiter("\n");     while (sc.hasNext()) {         String s = sc.next();         System.out.

  • VC++中HTControl的CHTButton按钮控件类用法实例解析

    本文以实例形式讲解了VC++中HTControl控件类的CHTButton按钮控件类用法,相信对大家更好的理解VC++有一定的帮助.具体内容如下: 一般了解VC++的朋友都知道,VC++ 按钮控件CHTButton隶属HTControl控件组,直接由WIN32 API实现,你可以在SDK,MFC,wxWidget等环境下使用它.支持生成各种类型的按钮,比如:普通按钮,PNG透明按钮,复选框按钮,单选按钮等.使用时请注意,窗体必须动态创建,代码段如下: m_HTBtnClose.Create(75

  • CI框架文件上传类及图像处理类用法分析

    本文实例讲述了CI框架文件上传类及图像处理类用法.分享给大家供大家参考,具体如下: //列表页banner图片 public function edit_list_page_banner($category_id=""){ $category_id= empty($category_id)?$_POST["category_id"]:$category_id; //上传图片 if(isset($_POST["key"]) && $

随机推荐