利用CImage完成图片的显示、拷贝、绘制及转换图片格式
2010-05-31 21:38
585 查看
近日一个利用VC编写的程序需要在界面上显示图片,经过查阅资料利用CImage方得实现。将相关技术点整理如下,以供以后参考。
一、 图片的载入
如果需要在界面上显示的是已经存在的图片,那么需要将待显示的图片载入至CImage对象之中,CImage提供了四个载入函数:
HRESULT Load(LPCTSTR pszFileName) throw( );
HRESULT Load(IStream* pStream) throw();
void LoadFromResource(HINSTANCE hInstance, LPCTSTR pszResourceName) throw( );
void LoadFromResource(HINSTANCE hInstance, UINT nIDResource) throw( );
如果需要显示的图片在程序运行时需要更换则通常使用第一个函数Load(LPCTSTR pszFileName)载入图片,参数pszFileName指定要载入的图片文件;如果需要显示的图片是固定不变的,则通常使用第三个LoadFromResource(HINSTANCE hInstance, LPCTSTR pszResourceName)或第四个函数LoadFromResource(HINSTANCE hInstance, UINT nIDResource)载入图片,这两个函数是从资源中取得图片信息,每一个参数是包含有待载入图片的模块实例句柄,第二个参数是资源的ID或名称。
以下代码分别通过Load和LoadFromResource载入了图片:
CImage m_image1; // 实际代码中,被声明成了类成员a
CImage m_image2; // 实际代码中,被声明成了类成员
m_image1.Load("G:\\VC显示图片\\PIC\\aa.jpg");
m_image2.LoadFromResource(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1));
二、 图片的显示
将图片载入CImage对象的目的是将其在界面之中显示出来,显示图像用到的核心函数是Draw,Draw提供了6个重载函数,通过参数名称,很容易了解参数的含义,其原型如下:
BOOL Draw(
HDC hDestDC,
int xDest,
int yDest,
int nDestWidth,
int nDestHeight,
int xSrc,
int ySrc,
int nSrcWidth,
int nSrcHeight
) const throw( );
BOOL Draw(
HDC hDestDC,
const RECT& rectDest,
const RECT& rectSrc
) const throw( );
BOOL Draw(
HDC hDestDC,
int xDest,
int yDest
) const throw( );
BOOL Draw(
HDC hDestDC,
const POINT& pointDest
) const throw( );
BOOL Draw(
HDC hDestDC,
int xDest,
int yDest,
int nDestWidth,
int nDestHeight
) const throw( );
BOOL Draw(
HDC hDestDC,
const RECT& rectDest
) const throw( );
如果要以控件的大小来显示图片,可以通过以下代码实现:
view plaincopy to clipboardprint?
if(m_image2.IsNull()) //判断有无图像
return;
// 取得客户区尺寸
CRect zcRect;
GetDlgItem(IDC_STATIC_PIC2)->GetClientRect(&zcRect);
// 将图像显示在界面之上
m_image2.Draw(GetDlgItem(IDC_STATIC_PIC2)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());
if(m_image2.IsNull()) //判断有无图像
return;
// 取得客户区尺寸
CRect zcRect;
GetDlgItem(IDC_STATIC_PIC2)->GetClientRect(&zcRect);
// 将图像显示在界面之上
m_image2.Draw(GetDlgItem(IDC_STATIC_PIC2)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());
如果希望以图像原图大小显示图像,则可以在显示图像之前通过SetWindowPos函数调整控件大小,使得图像可以以原始大小显示。以下代码演示了该情况:
view plaincopy to clipboardprint?
if(m_image1.IsNull())
return;
// 将整控件调整为与图像同一尺寸
GetDlgItem(IDC_STATIC_PIC)->SetWindowPos(NULL,
0,0,m_image1.GetWidth(), m_image1.GetHeight(),
SWP_NOMOVE);
CRect zcRect;
GetDlgItem(IDC_STATIC_PIC)->GetClientRect(&zcRect);
m_image1.Draw(GetDlgItem(IDC_STATIC_PIC)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());
if(m_image1.IsNull())
return;
// 将整控件调整为与图像同一尺寸
GetDlgItem(IDC_STATIC_PIC)->SetWindowPos(NULL,
0,0,m_image1.GetWidth(), m_image1.GetHeight(),
SWP_NOMOVE);
CRect zcRect;
GetDlgItem(IDC_STATIC_PIC)->GetClientRect(&zcRect);
m_image1.Draw(GetDlgItem(IDC_STATIC_PIC)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());
当然如果不在意控件尺寸必须与图像尺寸一致的话,也可以不调整控件尺寸,而直接在调用Draw方法时以图像尺寸来设定其第四个和第五个参数。
注意:显示出的图片在被其它窗口遮住以后,或者当前窗口最小化后,再次显示程序界面时刚才设定的图片将踪影全无,所以必须对它们进行重绘。因此可以将显示图片的代码放在一个单独的函数中,然后在OnPaint中进行调用(不知道有没有更简单的方法,希望知道的网友告诉我)。
三、 图片的拷贝
也可以利用CImage的BitBlt函数实现将一个图片拷贝至另一个图片之上,其效果相当于将一张图片放置于另一张图片之上。这个功能似乎不会经常用到。函数BitBlt的原型如下:
BOOL BitBlt(
HDC hDestDC,
int xDest,
int yDest,
DWORD dwROP = SRCCOPY
) const throw( );
BOOL BitBlt(
HDC hDestDC,
const POINT& pointDest,
DWORD dwROP = SRCCOPY
) const throw( );
BOOL BitBlt(
HDC hDestDC,
int xDest,
int yDest,
int nDestWidth,
int nDestHeight,
int xSrc,
int ySrc,
DWORD dwROP = SRCCOPY
) const throw( );
BOOL BitBlt(
HDC hDestDC,
const RECT& rectDest,
const POINT& pointSrc,
DWORD dwROP = SRCCOPY
) const throw( );
例如,希望将image2中存储的图像拷贝至image1中,可以通过以下代码实现:
m_image2.BitBlt(m_image1.GetDC(),0,0);
执行上述代码后,需要重新在界面绘制m_image1,否则只有在重新界面时拷贝的效果才可以显现出来。
四、 在内存中绘图
有时候需要在界面上动态绘图,但是如果直接在界面上绘图可能会引发闪烁的问题,可以通过先在CImage对象中绘图,然后将CImage对象显示于界面的方式降低这种感觉。假定m_image3是一个CImage对象,而我们需要画一个三角形然后将其在界面显示,可以通过以下代码完成。
view plaincopy to clipboardprint?
if(!m_image3.IsNull())
{
m_image3.Destroy();
}
m_image3.Create(100, 100, 32);
HDC hdc = m_image3.GetDC();
CDC *pDC=new CDC;
pDC->Attach(hdc);
CPen penRed(PS_SOLID, 2, RGB(255,0,0));
CPen* oldPen = pDC->SelectObject(&penRed);
pDC->MoveTo(50, 10);
pDC->LineTo(10,90);
pDC->LineTo(90,90);
pDC->LineTo(50,10);
DeleteObject(pDC->SelectObject(oldPen));
ReleaseDC(pDC);
CRect zcRect;
GetDlgItem(IDC_STATIC_PIC3)->GetClientRect(&zcRect);
m_image3.Draw(GetDlgItem(IDC_STATIC_PIC3)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());
if(!m_image3.IsNull())
{
m_image3.Destroy();
}
m_image3.Create(100, 100, 32);
HDC hdc = m_image3.GetDC();
CDC *pDC=new CDC;
pDC->Attach(hdc);
CPen penRed(PS_SOLID, 2, RGB(255,0,0));
CPen* oldPen = pDC->SelectObject(&penRed);
pDC->MoveTo(50, 10);
pDC->LineTo(10,90);
pDC->LineTo(90,90);
pDC->LineTo(50,10);
DeleteObject(pDC->SelectObject(oldPen));
ReleaseDC(pDC);
CRect zcRect;
GetDlgItem(IDC_STATIC_PIC3)->GetClientRect(&zcRect);
m_image3.Draw(GetDlgItem(IDC_STATIC_PIC3)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());
五、 转换图片格式
通过CImage的Load函数可以导入多种格式的图片文件,或者我们也可以直接在内存中绘制出一张图画,这些图像信息最终可能需要转换成指定的图片压缩格式。利用CImage的Save函数完成这种转换是非常容易的。函数Save的原型如下:
HRESULT Save(
IStream* pStream,
REFGUID guidFileType
) const throw();
HRESULT Save(
LPCTSTR pszFileName,
REFGUID guidFileType= GUID_NULL
) const throw();
参数guidFileType指定了需要保存的结果类型,其允许的值及含义如下:
ImageFormatBMP 未压缩的位图
ImageFormatPNG PNG压缩格式
ImageFormatJPEG JPEG 压缩格式
ImageFormatGIF GIF压缩格式
对于Save函数的第二种重载形式,也可以将guidFileType设定为GUID_NULL或者不设定(guidFileType将默认为GUID_NULL),此时Save函数将通过第一个参数pszFileName指定的文件名后缀的值来识别需要保存的格式。例如m_image1中导入的是JPEG格式的图片,通过以下代码,可以将其转换成后缀为.bmp的位图及后缀为.gif的GIF压缩格式图。
m_image1.Save("G:\\aa.bmp");
m_image1.Save("G:\\aa.gif");
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ishallwin/archive/2009/11/20/4840180.aspx
一、 图片的载入
如果需要在界面上显示的是已经存在的图片,那么需要将待显示的图片载入至CImage对象之中,CImage提供了四个载入函数:
HRESULT Load(LPCTSTR pszFileName) throw( );
HRESULT Load(IStream* pStream) throw();
void LoadFromResource(HINSTANCE hInstance, LPCTSTR pszResourceName) throw( );
void LoadFromResource(HINSTANCE hInstance, UINT nIDResource) throw( );
如果需要显示的图片在程序运行时需要更换则通常使用第一个函数Load(LPCTSTR pszFileName)载入图片,参数pszFileName指定要载入的图片文件;如果需要显示的图片是固定不变的,则通常使用第三个LoadFromResource(HINSTANCE hInstance, LPCTSTR pszResourceName)或第四个函数LoadFromResource(HINSTANCE hInstance, UINT nIDResource)载入图片,这两个函数是从资源中取得图片信息,每一个参数是包含有待载入图片的模块实例句柄,第二个参数是资源的ID或名称。
以下代码分别通过Load和LoadFromResource载入了图片:
CImage m_image1; // 实际代码中,被声明成了类成员a
CImage m_image2; // 实际代码中,被声明成了类成员
m_image1.Load("G:\\VC显示图片\\PIC\\aa.jpg");
m_image2.LoadFromResource(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP1));
二、 图片的显示
将图片载入CImage对象的目的是将其在界面之中显示出来,显示图像用到的核心函数是Draw,Draw提供了6个重载函数,通过参数名称,很容易了解参数的含义,其原型如下:
BOOL Draw(
HDC hDestDC,
int xDest,
int yDest,
int nDestWidth,
int nDestHeight,
int xSrc,
int ySrc,
int nSrcWidth,
int nSrcHeight
) const throw( );
BOOL Draw(
HDC hDestDC,
const RECT& rectDest,
const RECT& rectSrc
) const throw( );
BOOL Draw(
HDC hDestDC,
int xDest,
int yDest
) const throw( );
BOOL Draw(
HDC hDestDC,
const POINT& pointDest
) const throw( );
BOOL Draw(
HDC hDestDC,
int xDest,
int yDest,
int nDestWidth,
int nDestHeight
) const throw( );
BOOL Draw(
HDC hDestDC,
const RECT& rectDest
) const throw( );
如果要以控件的大小来显示图片,可以通过以下代码实现:
view plaincopy to clipboardprint?
if(m_image2.IsNull()) //判断有无图像
return;
// 取得客户区尺寸
CRect zcRect;
GetDlgItem(IDC_STATIC_PIC2)->GetClientRect(&zcRect);
// 将图像显示在界面之上
m_image2.Draw(GetDlgItem(IDC_STATIC_PIC2)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());
if(m_image2.IsNull()) //判断有无图像
return;
// 取得客户区尺寸
CRect zcRect;
GetDlgItem(IDC_STATIC_PIC2)->GetClientRect(&zcRect);
// 将图像显示在界面之上
m_image2.Draw(GetDlgItem(IDC_STATIC_PIC2)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());
如果希望以图像原图大小显示图像,则可以在显示图像之前通过SetWindowPos函数调整控件大小,使得图像可以以原始大小显示。以下代码演示了该情况:
view plaincopy to clipboardprint?
if(m_image1.IsNull())
return;
// 将整控件调整为与图像同一尺寸
GetDlgItem(IDC_STATIC_PIC)->SetWindowPos(NULL,
0,0,m_image1.GetWidth(), m_image1.GetHeight(),
SWP_NOMOVE);
CRect zcRect;
GetDlgItem(IDC_STATIC_PIC)->GetClientRect(&zcRect);
m_image1.Draw(GetDlgItem(IDC_STATIC_PIC)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());
if(m_image1.IsNull())
return;
// 将整控件调整为与图像同一尺寸
GetDlgItem(IDC_STATIC_PIC)->SetWindowPos(NULL,
0,0,m_image1.GetWidth(), m_image1.GetHeight(),
SWP_NOMOVE);
CRect zcRect;
GetDlgItem(IDC_STATIC_PIC)->GetClientRect(&zcRect);
m_image1.Draw(GetDlgItem(IDC_STATIC_PIC)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());
当然如果不在意控件尺寸必须与图像尺寸一致的话,也可以不调整控件尺寸,而直接在调用Draw方法时以图像尺寸来设定其第四个和第五个参数。
注意:显示出的图片在被其它窗口遮住以后,或者当前窗口最小化后,再次显示程序界面时刚才设定的图片将踪影全无,所以必须对它们进行重绘。因此可以将显示图片的代码放在一个单独的函数中,然后在OnPaint中进行调用(不知道有没有更简单的方法,希望知道的网友告诉我)。
三、 图片的拷贝
也可以利用CImage的BitBlt函数实现将一个图片拷贝至另一个图片之上,其效果相当于将一张图片放置于另一张图片之上。这个功能似乎不会经常用到。函数BitBlt的原型如下:
BOOL BitBlt(
HDC hDestDC,
int xDest,
int yDest,
DWORD dwROP = SRCCOPY
) const throw( );
BOOL BitBlt(
HDC hDestDC,
const POINT& pointDest,
DWORD dwROP = SRCCOPY
) const throw( );
BOOL BitBlt(
HDC hDestDC,
int xDest,
int yDest,
int nDestWidth,
int nDestHeight,
int xSrc,
int ySrc,
DWORD dwROP = SRCCOPY
) const throw( );
BOOL BitBlt(
HDC hDestDC,
const RECT& rectDest,
const POINT& pointSrc,
DWORD dwROP = SRCCOPY
) const throw( );
例如,希望将image2中存储的图像拷贝至image1中,可以通过以下代码实现:
m_image2.BitBlt(m_image1.GetDC(),0,0);
执行上述代码后,需要重新在界面绘制m_image1,否则只有在重新界面时拷贝的效果才可以显现出来。
四、 在内存中绘图
有时候需要在界面上动态绘图,但是如果直接在界面上绘图可能会引发闪烁的问题,可以通过先在CImage对象中绘图,然后将CImage对象显示于界面的方式降低这种感觉。假定m_image3是一个CImage对象,而我们需要画一个三角形然后将其在界面显示,可以通过以下代码完成。
view plaincopy to clipboardprint?
if(!m_image3.IsNull())
{
m_image3.Destroy();
}
m_image3.Create(100, 100, 32);
HDC hdc = m_image3.GetDC();
CDC *pDC=new CDC;
pDC->Attach(hdc);
CPen penRed(PS_SOLID, 2, RGB(255,0,0));
CPen* oldPen = pDC->SelectObject(&penRed);
pDC->MoveTo(50, 10);
pDC->LineTo(10,90);
pDC->LineTo(90,90);
pDC->LineTo(50,10);
DeleteObject(pDC->SelectObject(oldPen));
ReleaseDC(pDC);
CRect zcRect;
GetDlgItem(IDC_STATIC_PIC3)->GetClientRect(&zcRect);
m_image3.Draw(GetDlgItem(IDC_STATIC_PIC3)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());
if(!m_image3.IsNull())
{
m_image3.Destroy();
}
m_image3.Create(100, 100, 32);
HDC hdc = m_image3.GetDC();
CDC *pDC=new CDC;
pDC->Attach(hdc);
CPen penRed(PS_SOLID, 2, RGB(255,0,0));
CPen* oldPen = pDC->SelectObject(&penRed);
pDC->MoveTo(50, 10);
pDC->LineTo(10,90);
pDC->LineTo(90,90);
pDC->LineTo(50,10);
DeleteObject(pDC->SelectObject(oldPen));
ReleaseDC(pDC);
CRect zcRect;
GetDlgItem(IDC_STATIC_PIC3)->GetClientRect(&zcRect);
m_image3.Draw(GetDlgItem(IDC_STATIC_PIC3)->GetDC()->m_hDC,
zcRect.left,
zcRect.top,
zcRect.Width(),
zcRect.Height());
五、 转换图片格式
通过CImage的Load函数可以导入多种格式的图片文件,或者我们也可以直接在内存中绘制出一张图画,这些图像信息最终可能需要转换成指定的图片压缩格式。利用CImage的Save函数完成这种转换是非常容易的。函数Save的原型如下:
HRESULT Save(
IStream* pStream,
REFGUID guidFileType
) const throw();
HRESULT Save(
LPCTSTR pszFileName,
REFGUID guidFileType= GUID_NULL
) const throw();
参数guidFileType指定了需要保存的结果类型,其允许的值及含义如下:
ImageFormatBMP 未压缩的位图
ImageFormatPNG PNG压缩格式
ImageFormatJPEG JPEG 压缩格式
ImageFormatGIF GIF压缩格式
对于Save函数的第二种重载形式,也可以将guidFileType设定为GUID_NULL或者不设定(guidFileType将默认为GUID_NULL),此时Save函数将通过第一个参数pszFileName指定的文件名后缀的值来识别需要保存的格式。例如m_image1中导入的是JPEG格式的图片,通过以下代码,可以将其转换成后缀为.bmp的位图及后缀为.gif的GIF压缩格式图。
m_image1.Save("G:\\aa.bmp");
m_image1.Save("G:\\aa.gif");
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ishallwin/archive/2009/11/20/4840180.aspx
相关文章推荐
- 利用CImage完成图片的显示、拷贝、绘制及转换图片格式
- 利用CImage完成图片的显示、拷贝、绘制及转换图片格式
- 利用CImage完成图片的显示、拷贝、绘制及转换图片格式
- 利用CImage完成图片的显示、拷贝、绘制及转换图片格式 .
- 利用CImage完成图片的显示、拷贝、绘制及转换图片格式
- 利用CImage完成图片的显示、拷贝、绘制及转换图片格式
- 利用CImage完成图片的显示、拷贝、绘制及转换图片格式
- 在VC中使用CImage转换图片格式,显示jpg等格式图片
- 在VC中使用CImage转换图片格式,显示jpg等格式图片
- 在VC中使用CImage转换图片格式以及显示
- 利用jpedal进行pdf转换成jpeg,jpg,png,tiff,tif等格式的图片
- 利用数据库如何存入BLOB格式图片,并从数据库中取出BLBO格式图片显示出来
- Java平台要实现类似豆丁百度文科的文档在线阅读,总体思路是讲doc docx等文件格式利用jcom转换成pdf再用swftools转为swf。再用flexpaper组件显示swf。
- 利用jacob完成文档格式的转换(PDF)
- Python实例2-获取某文件夹下指定类型的图片名,完成图片格式的转换并保存
- MFC利用CImage类将图片显示到Picture控件上
- 利用jpedal进行pdf转换成jpeg,jpg,png,tiff,tif等格式的图片
- 利用opencv将本地图片转换成ROS格式
- 如何利用CImage和AlphaBlend绘制PNG图片?
- winform利用itextsharp.dll实现图片文件转换PDF格式文件