引入CImage类的原因
原有的CBitmap 类只能处理BMP格式的图片,非常受限。而CImage可以处理JPGE、GIF、BMP、PNG等多种格式图片,扩展了图片处理功能且能与CBitmap 进行转换( 因为所载入的位图句柄都是HBITMAP,所以可相互转换),因此引入CImage类进行图像处理。
CImage类简介
CImage是MFC和ATL共享的新类,它能从外部磁盘中调入一个JPEG、GIF、BMP和PNG格式的图像文件加以显示,而且这些文件格式可以相互转换。
CImage提供增强型的(DDB和DIB)位图支持,可以装入、显示、转换和保存多种格式的图像文件,包括BMP、GIF、JPG、PNG、TIF等。CImage是一个独立的类,没有基类。(CImage类是基于GDI+的,从VC起引进,VC 6.0中没有)
CImage类成员
头文件为atlimage.h,主要用于图片文件的打开,显示与保存。这里需要注意的是,在VS2010和VS2012的MFC编程中,不需要将头文件包含进来。MFC中要使用CImage类,必须先将头文件包含进来,可以包含在当前代码的CPP文件中,也可以包含在所属类的头文件中,不过最好还是包含在工程的stdafx.h文件中。
CImage类的成员可分为连接与创建、输入与输出、位图类型与参数,以及图形绘制与位图块传送等4类。
(1) 连接与创建
Attach 将一个DIB(或DDB)位图与CImage对象相连接
Detach 位图与CImage对象相分离
Create 创建一个DIB位图并将它与已有CImage对象相连接
Destroy 位图与Cimage对象相分离并删除
(2) 输入与输出
GetImporterFilterString 返回系统支持的输入文件格式类型及其描述
GetExporterFilterString 返回系统支持的输出文件格式类型及其描述
Load 读入指定图像文件中的图像
LoadFromResource 读入指定资源文件中的图像
Save 按指定类型保存图像,文件名中不能省略后缀
IsNull 判别源图像文件是否已经读入
(3) 位图类型与参数
GetWidth 返回当前图像的宽度(以像素为单位)
GetHeight 返回当前图像的高度
GetBPP 返回当前图像的每像素位数
GetBits 返回当前图像像素数据的指针
GetPitch 返回相邻两行像素首地址之间的间隔
GetPixelAddress 返回指定像素数据存放位置的存储地址
GetMaxColorTableEntries返回调色板单元数
IsDibSection 确定位图是否为DIB位图
IsIndexed 判别位图中是否有调色板
IsTransparencySupported判别应用程序是否支持透明位图
AlphaBlend 是否支持透明或半透明显示的状态
(4) 图形绘绘与位图块传送
GetDC 返回当前位图的设备描述表
ReleaseDC 释放设备描述表
GetPixel 返回指定位置像素的颜色
SetPixel 设置指定位置像素的颜色
SetPixelIndexed 设置指定位置像素颜色的索引值
SetPixelRGB 设置指定位置像素的红绿蓝分量
GetColorTable 获取调色板颜色分量(红、绿、蓝)值
SetColorTable 设置调色板颜色分量(红、绿、蓝)值
SetTransparentColor 设置透明颜色的索引值,只能有一种颜色可为透明
Draw 从源矩形复制到目标矩形,支持伸缩、a融合与透明
BitBlt 位图的一个举行区域复制到另一位图上的制定区域
MaskBlt 为图块传送时须与指定的模板图像做逻辑操作
PlgBlt 为图的矩形区域到另一位图上平行四边形间的位块传输
StretchBlt 从源矩形复制到目标矩形,支持伸缩
TransparentBlt 位图块传送时复制带透明色的位图
源码
不多说,直接上源码
头文件:
#ifndef _AFXSTD_507A8D18_E3C1_47AA_8892_41786A393718_INCLUDE_H_
#define _AFXSTD_507A8D18_E3C1_47AA_8892_41786A393718_INCLUDE_H_
#if _MSC_VER > 1200
#pragma once
#endif //!_MSC_VER > 1200
#include
#include
using namespace std;
//====================================CImageEx====================================
/// @brief 图像处理类
///
/// 格式: BMP、GIF、JPG、PNG、TIF等
/// 功能: 图像加载、保存
/// 图像信息的获取
/// 图像数据的获取与修改
/// 位图的绑定与获取
/// 图像绘制...
//================================================================================
class CImageEx
{
public:
CImageEx();
~CImageEx();
public:
//通过文件路径imagePath加载图像,必须带后缀
HRESULT LoadImage(string &imagePath);
//指定文件路径imagePath保存图像,必须带后缀
HRESULT SaveImage(string &imagePath);
//图像宽度(以像素为单位)
int GetWidth();
//图像高度(以像素为单位)
int GetHeight();
//图像数据
BYTE *GetData();
//每行的字节数
//值 > 0 图像方向为从上到下, GetData()获得的指针指向第一行
//值 < 0 图像方向为从下到上, GetData()获得的指针指向最后一行
int GetRowBytes();
//每个像素所占的bit数
int GetBPP();
//设置位置为x、y的像素的颜色
void SetPixelColor(int x, int y, int color);
void SetPixelColor(int x, int y, int r, int g, int b);
//获取位置为x、y的像素的颜色
int GetPixelColor(int x, int y);
//获取位置为x、y的像素的颜色内存数据
void *GetPixelAddress( int x, int y );
//将一个DIB(或DDB)位图与CImage对象相连接
void AttachHBitMap(HBITMAP &pHbitMap);
//返回HBITMAP位图句柄
HRESULT DetachHBitMap(HBITMAP &pHbitMap);
//返回CBitMap
CBitmap *GetBitmap();
//将数据绘制到hWnd的窗体上
void Draw(HWND hWnd);
//将数据绘制保存到位图路径imagePath中
//宽度为 width,长度为 heigth
void DrawToBitMap(string &imagePath, int width, int heigth);
//获取CImage
CImage *GetImagePtr();
private:
CImage *m_pImage;
};
#endif //!_AFXSTD_507A8D18_E3C1_47AA_8892_41786A393718_INCLUDE_H_
cpp文件:
#include "stdafx.h"
#include
#include "Image.h"
CImageEx::CImageEx()
{
m_pImage = NULL;
}
CImageEx::~CImageEx()
{
if (NULL != m_pImage)
{
m_pImage->Destroy();
}
}
HRESULT CImageEx::LoadImage( string &imagePath )
{
if (NULL != m_pImage && !m_pImage->IsNull())
{
m_pImage->Destroy();
}
if (NULL == m_pImage)
{
m_pImage = new CImage;
}
return( m_pImage->Load((CString)imagePath.c_str()) );
}
CImage * CImageEx::GetImagePtr()
{
return(m_pImage);
}
HRESULT CImageEx::DetachHBitMap( HBITMAP &pHbitMap )
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return(E_POINTER);
}
pHbitMap = m_pImage->Detach();
return(S_OK);
}
CBitmap * CImageEx::GetBitmap()
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return(NULL);
}
return(CBitmap::FromHandle(m_pImage->Detach()));
}
BYTE * CImageEx::GetData()
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return(NULL);
}
return ( (BYTE *)m_pImage->GetBits() );
}
int CImageEx::GetRowBytes()
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return(0);
}
return ( m_pImage->GetPitch() );
}
int CImageEx::GetBPP()
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return(0);
}
return ( m_pImage->GetBPP() );
}
int CImageEx::GetWidth()
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return(0);
}
return ( m_pImage->GetWidth() );
}
int CImageEx::GetHeight()
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return(0);
}
return ( m_pImage->GetHeight() );
}
HRESULT CImageEx::SaveImage( string &imagePath )
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return(0);
}
return ( m_pImage->Save((CString)imagePath.c_str()) );
}
void CImageEx::AttachHBitMap( HBITMAP &pHbitMap )
{
if (NULL != m_pImage && !m_pImage->IsNull())
{
m_pImage->Destroy();
}
if (NULL == m_pImage)
{
m_pImage = new CImage;
}
m_pImage->Attach(pHbitMap);
}
void CImageEx::SetPixelColor( int x, int y, int color )
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return;
}
m_pImage->SetPixel(x, y, (COLORREF)(color));
}
void CImageEx::SetPixelColor( int x, int y, int r, int g, int b )
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return;
}
m_pImage->SetPixelRGB(x, y, r, g, b);
}
int CImageEx::GetPixelColor( int x, int y )
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return(0);
}
return(m_pImage->GetPixel(x, y));
}
void *CImageEx::GetPixelAddress( int x, int y )
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return(NULL);
}
return(m_pImage->GetPixelAddress(x, y));
}
void CImageEx::Draw( HWND hWnd )
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return;
}
RECT rect;
HDC hDC = GetDC(hWnd);
::GetClientRect(hWnd, &rect);
m_pImage->Draw(hDC, rect);
//窗体重绘事件使用BeginPaint与EndPaint
}
void CImageEx::DrawToBitMap(string &imagePath, int width, int heigth)
{
if (NULL == m_pImage || m_pImage->IsNull())
{
return;
}
HDC hDC = m_pImage->GetDC();
CDC *pCDC = CDC::FromHandle(hDC);
//创建位图
CBitmap *pBitMap = new CBitmap;
pBitMap->DeleteObject();
pBitMap->CreateCompatibleBitmap(pCDC, width, heigth);
//创建绘制DC,绑定pBitMap
CDC memDC;
memDC.CreateCompatibleDC(pCDC);
CBitmap *pOldBitMap = memDC.SelectObject(pBitMap);
//将图像绘制到pBitMap中
::SetStretchBltMode(memDC.m_hDC, HALFTONE);
::SetBrushOrgEx(memDC.m_hDC, 0, 0, NULL);
m_pImage->StretchBlt(memDC.m_hDC, 0, 0, width, heigth, 0, 0, m_pImage->GetWidth(), m_pImage->GetHeight(), SRCCOPY);
HBITMAP hBitMap = (HBITMAP)memDC.SelectObject(pOldBitMap->m_hObject); //位图资源
//保存到目的路径
CImage imageDes;
imageDes.Attach(hBitMap);
imageDes.Save((CString)imagePath.c_str());
memDC.DeleteDC();
if (NULL != pBitMap)
{
pBitMap->DeleteObject();
delete pBitMap;
}
m_pImage->ReleaseDC();
}
测试程序:
CImageEx imageEx;
imageEx.LoadImage(string("C:\\Tulip.jpg"));
imageEx.DrawToBitMap(string("C:\\Tulip2.jpg"), 200, 100);
参考文章:http://mazhg430.blog.163.com/blog/static/11508091320105183382988/