GDI入门实例(在VC++6.0中将JPG格式图片转换成BMP格式)

在 VC++6.0 中将 JPG 格式图片转换成 BMP 格式

思路:利用 GDI+来完成
难点: (1)配置 GDI 开发环境,添加配置代码
(2)在当文档程序中添加转换代码
注意:本文档由 ybdesire 参考网上资料撰写完成,代码已经做过测试,可直接复制张贴


实现过程:

一、 配置 GDI 开发环境
(1) 下载 GDI+ SDK for Visual C++ 6.0
http://www.codeguru.com/code/legacy/gdi/GDIPlus.zip
下载的GDIPlus文件夹中有Includes,Lib文件夹和gdiplus.dll文件。
将Includes和Lib中的文件分别拷到VC6安装目录中的VC98\include和lib文件夹下。

(2) 新建 MFC 单文档应用程序 show:

  1. #include <afxdtctl.h>   
  2. #define ULONG_PTR ULONG   
  3. #include <gdiplus.h>   
  4. using namespace Gdiplus;  
  5. #pragma comment(lib, "gdiplus.lib")  
#include <afxdtctl.h>
#define ULONG_PTR ULONG
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment(lib, "gdiplus.lib")

2、如(1)中所说,将gdiplus.dll拷贝到本工程的Debug或Release目录下

3、在show.h中的class CShowApp : public CWinApp中添加

  1. private:  
  2.     GdiplusStartupInput m_gdiplusStartupInput;  
  3.     ULONG_PTR m_pGdiToken;  
private:
    GdiplusStartupInput m_gdiplusStartupInput;
    ULONG_PTR m_pGdiToken;

4、在show.cpp中的BOOL CShowApp::InitInstance()中添加
  1. GdiplusStartup(&m_pGdiToken,&m_gdiplusStartupInput,NULL);  
    GdiplusStartup(&m_pGdiToken,&m_gdiplusStartupInput,NULL);

5、 CShowApp添加名字为ExitInstance的虚函数的,中添加如下退出GDI+的代码
  1. GdiplusShutdown(m_pGdiToken);  
GdiplusShutdown(m_pGdiToken);

(3) 测试 GDI+是否配置成功
  1. void CShowView::OnDraw(CDC* pDC)  
  2. {  
  3.     CShowDoc* pDoc = GetDocument();  
  4.     ASSERT_VALID(pDoc);  
  5.     Graphics graphics(pDC->m_hDC);  
  6.     Pen pen(Color(255, 0, 255));  
  7.     graphics.DrawLine(&pen, 0, 0, 200, 100);  
  8. }  
void CShowView::OnDraw(CDC* pDC)
{
    CShowDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    Graphics graphics(pDC->m_hDC);
    Pen pen(Color(255, 0, 255));
    graphics.DrawLine(&pen, 0, 0, 200, 100);
}

若能成功运行,表明GDI+配置成功


二、 添加转换代码,实现将打开的 JPG 格式文件保存成 BMP 格式文件


(1)在 CSshowView 中添加如下成员变量


  1. CString strOpenFileName;  
CString strOpenFileName;

(2)在 CSshowView 中添加如下成员函数
1、在 CSshowView 中添加 ToWChar 函数

  1. WCHAR* CShowView::ToWChar(char *str)  
  2. {  
  3.     //在 GDI+中,有关字符的参数类型全部都是 WCHAR 类型的   
  4.     //该函数是将传统字符串进行转换   
  5.     static WCHAR buffer[1024];  
  6.     wcsset(buffer,0);  
  7.     MultiByteToWideChar(CP_ACP,0,str,strlen(str),buffer,1024);  
  8.     return buffer;  
  9. }  
WCHAR* CShowView::ToWChar(char *str)
{
    //在 GDI+中,有关字符的参数类型全部都是 WCHAR 类型的
    //该函数是将传统字符串进行转换
    static WCHAR buffer[1024];
    wcsset(buffer,0);
    MultiByteToWideChar(CP_ACP,0,str,strlen(str),buffer,1024);
    return buffer;
}

2、在 CSshowView 中添加 GetImageCLSID 函数

  1. int CShowView::GetImageCLSID(const WCHAR *format, CLSID *pCLSID)  
  2. {  
  3.     UINT num=0;  
  4.     UINT size=0;  
  5.     ImageCodecInfo* pImageCodecInfo=NULL;  
  6.     GetImageEncodersSize(&num,&size);  
  7.     if(size==0)  
  8.         return FALSE; // 编码信息不可用   
  9.     // 分配内存   
  10.     pImageCodecInfo=(ImageCodecInfo*)(malloc(size));  
  11.     if(pImageCodecInfo==NULL)  
  12.         return FALSE; // 分配失败   
  13.     // 获得系统中可用的编码方式的所有信息   
  14.     GetImageEncoders(num,size,pImageCodecInfo);  
  15.     // 在可用编码信息中查找 format 格式是否被支持   
  16.   
  17.     for(UINT i=0;i<num;++i)  
  18.     {  
  19.         //MimeType: 编码方式的具体描述   
  20.         if (wcscmp(pImageCodecInfo[ i] .MimeType,format)==0)  
  21.         {  
  22.             *pCLSID=pImageCodecInfo[i].Clsid;  
  23.             free(pImageCodecInfo);  
  24.             return TRUE;  
  25.         }  
  26.     }  
  27.     free(pImageCodecInfo);  
  28.     return FALSE;  
  29. }  
int CShowView::GetImageCLSID(const WCHAR *format, CLSID *pCLSID)
{
    UINT num=0;
    UINT size=0;
    ImageCodecInfo* pImageCodecInfo=NULL;
    GetImageEncodersSize(&num,&size);
    if(size==0)
        return FALSE; // 编码信息不可用
    // 分配内存
    pImageCodecInfo=(ImageCodecInfo*)(malloc(size));
    if(pImageCodecInfo==NULL)
        return FALSE; // 分配失败
    // 获得系统中可用的编码方式的所有信息
    GetImageEncoders(num,size,pImageCodecInfo);
    // 在可用编码信息中查找 format 格式是否被支持

    for(UINT i=0;i<num;++i)
    {
        //MimeType: 编码方式的具体描述
        if (wcscmp(pImageCodecInfo[ i] .MimeType,format)==0)
        {
            *pCLSID=pImageCodecInfo[i].Clsid;
            free(pImageCodecInfo);
            return TRUE;
        }
    }
    free(pImageCodecInfo);
    return FALSE;
}

3、在 MFC ClassWixard 中重载 OnFileOpen()

  1. void CShowView::OnFileOpen()  
  2. {  
  3.     static char szFilter[ ]="常见图像格式文件(*.*)|*.*|";  
  4.     CFileDialog dlgChoseImage(1,NULL,NULL,NULL,szFilter);  
  5.     if(dlgChoseImage.DoModal() ==IDOK)  
  6.     {  
  7.         strOpenFileName=dlgChoseImage.GetPathName();  
  8.         // 打开文件后立即在窗口中显示 (重绘客户窗口)   
  9.         this->Invalidate() ;  
  10.     }  
  11. }  
void CShowView::OnFileOpen()
{
    static char szFilter[ ]="常见图像格式文件(*.*)|*.*|";
    CFileDialog dlgChoseImage(1,NULL,NULL,NULL,szFilter);
    if(dlgChoseImage.DoModal() ==IDOK)
    {
        strOpenFileName=dlgChoseImage.GetPathName();
        // 打开文件后立即在窗口中显示 (重绘客户窗口)
        this->Invalidate() ;
    }
}

4、在 MFC ClassWixard 中重载 OnFileSave()

  1. void CShowView::OnFileSave()  
  2. {  
  3.     if( strOpenFileName.IsEmpty() )  
  4.     {  
  5.         AfxMessageBox("当前没有打开图像文件, 不能进行保存!");  
  6.         return;  
  7.     }  
  8.   
  9.     // 建立图形对象   
  10.     Graphics graphics(GetDC()->m_hDC);  
  11.   
  12.     // 装入当前已经打开的图像文件   
  13.     Image image(ToWChar(strOpenFileName.GetBuffer(strOpenFileName.GetLength())));  
  14.   
  15.     CString strFileSave;  
  16.     // 将其他格式的图像全部另存为 BMP 文件   
  17.     static char szFilter[ ]= "位图(*.BMP)|*.BMP|";  
  18.   
  19.     CFileDialog dlgChoseImage(0,"BMP",strOpenFileName,NULL,szFilter);  
  20.   
  21.     if(dlgChoseImage.DoModal() ==IDOK)  
  22.   
  23.     {  
  24.   
  25.         strFileSave=dlgChoseImage.GetPathName();  
  26.   
  27.         CLSID clsid;  
  28.   
  29.         if(GetImageCLSID(L"image/bmp", &clsid))  
  30.         {  
  31.             image.Save(ToWChar(strFileSave.GetBuffer(strFileSave.GetLength())), &clsid, NULL);  
  32.             // 将保存后的图像进行显示   
  33.             strOpenFileName=strFileSave;  
  34.             this->Invalidate() ;  
  35.         }  
  36.     }  
  37. }  
void CShowView::OnFileSave()
{
    if( strOpenFileName.IsEmpty() )
    {
        AfxMessageBox("当前没有打开图像文件, 不能进行保存!");
        return;
    }

    // 建立图形对象
    Graphics graphics(GetDC()->m_hDC);

    // 装入当前已经打开的图像文件
    Image image(ToWChar(strOpenFileName.GetBuffer(strOpenFileName.GetLength())));

    CString strFileSave;
    // 将其他格式的图像全部另存为 BMP 文件
    static char szFilter[ ]= "位图(*.BMP)|*.BMP|";

    CFileDialog dlgChoseImage(0,"BMP",strOpenFileName,NULL,szFilter);

    if(dlgChoseImage.DoModal() ==IDOK)

    {

        strFileSave=dlgChoseImage.GetPathName();

        CLSID clsid;

        if(GetImageCLSID(L"image/bmp", &clsid))
        {
            image.Save(ToWChar(strFileSave.GetBuffer(strFileSave.GetLength())), &clsid, NULL);
            // 将保存后的图像进行显示
            strOpenFileName=strFileSave;
            this->Invalidate() ;
        }
    }
}

参考资料

[1]http://blog.csdn.net/poonjun/archive/2009/01/04/3701724.aspx
[2]http://www.cnblogs.com/DavidHu/articles/1191635.html
[3]http://www.smth.edu.cn/bbsgcon.php?board=VisualC&num=785
[4]《图像格式转换在数字仪表识别系统中的应用》 刘 娜, 汪仁煌, 庞 然

扩展知识阅读

    [3] 色彩鲜艳漂亮的高品质图像,一个个形象的Windows图标,高速运动、活灵活现的三维动画,这些生动的图形无一不显示着程序设计者的艺术才华。在程序设计中,图像处理已经成了每个程序员的必修课,所以,对于每个程序员来说,熟悉“BMP”、“GIF”、“JPEG”图像格式及具体应用、调色板、图像文件头格式、图像压缩算法等概念似乎已经成了工作中不可缺少的基础知识。面对如此多的图像格式,如果要全部掌握其具体细节,好像这对程序员有些不公。在VC中编程显示一幅位图,下列的步骤是不可少的:装入位图、获得位图的大小信息、启用设备环境、位传输,所需的程序代码显得千篇一律的冗长。如果想要装入的位图另存为其他格式的图像文件……?两个字:头疼!而这一 切都是因为GDI本身的局限性所造成。

    随着Windows 2000的推出,上面的情况有了大大的改观:你可以不必了解每种图像格式的具体含义,照样可以写出多格式图像浏览或转换程序,这一切,全部都依赖于Windows 2000及后继版中所使用的GDI+技术。首先来看看GDI+的具体技术细节及GDI+编程特点。

    Windows 2000在用户界面方面包括了几个重大的改进,可能你已经注意到了有阴影的鼠 标、渐入的工具条快速提示、透明的窗口、平滑地窗口变化等。Windows 2000在界面上之所以有这么大的改进,完全是因为Windows2000采用了一种GDI(graphics device interface :图形设备接口)。GDI+是一种新型的图形设备接口,它的主要特点在于它能够创建全新的用户桌面 体系、能够轻易地完成二维或三维的图形处理,为桌面带来一种数字化的图片。 GDI+同时也提供了增强的图形处理技术,如常见的:alpha blending、 纹理、贴图、增强的文本及图片显示技术。实际上,GDI+主要的特色就在于强调通过硬件加速来达到良好的 视觉感受!

    同传统的GDI不同,GDI+中引入了对COM(组件对象模型)技术的支持,通过COM技术,GDI+简化了对图像文件的访问(打开、保存)程序:通过调用COM组件来实现的,GDI+扮演的只是指挥者,而非操作员。对于图像文件,GDI+所关心的不是图像文件的文件头信息,不论欲打开的文件格式是什么类型,GDI+首先要做的是在注册中查看该图像格式的编码(或解码)信息是否已经注册(HKEY_CLASSES_ROOT\MIME\Database\Content Type)

    在微软的其他软件中已经使用了,如IE。“体验”过NIMDA病毒的朋友可能对“audio/wav”这段代码并不陌生,NIMDA就是靠它来伪装自己的:让IE认为附件是WAV文件而自动打开可执行程序。这其实也是IE使用COM技术的一个突出表现。
配合GDI+的推出,微软也同时发布了相应的SDK,如果你已经安装了最新的Microsoft PlatForm SDK或已经开始使用VS .NET,GDI+ SDK已经在你的系统中了。如果没有的话,可以到http://noner.top263.net/progtool上去下载GDI+的头文件和库文件。在使用GDI+之后,, 再有没有必要去考虑什么句柄、设备环境这样的概念了。你只需要简单地创建一个图形对象(Graphics object)绘图即可。图形对象是GDI+中核心,正如DC之于GDI那样。图形对象和DC有许多相似的地方,在使用上遵循着相同的使用规则,但是两者在本质上已经有很大的区别。一个是基于句柄的GDI,一个是基于组件对象模型的GDI+。使用GDI+的SDK编程,必须得按照下面的规范来进行:使用GDI+的名空间(namespace Gdiplus)进行GDI+的初始化,使用完毕之后也得销毁GDI+,这种规范在下面所列的程序中有详细的说明。前面说到了GDI+是通过在注册中查看编码信息来访问图像文件的,在GDI+的SDK中,编码信息是储存在 ImageCodecInfo类中的,在这个类中,有编码的CLSID(COM组件的GUID标识码)

    数来实现:

    1、查看系统中可用的图像编码信息(数量及大小)

  1. Status GetImageEncodersSize(  
  2.     UINT* numEncoders, //存储编码器数量的地址   
  3.     UINT* size //存储编码信息所需内存大小   
  4.     );  
Status GetImageEncodersSize(
    UINT* numEncoders, //存储编码器数量的地址
    UINT* size //存储编码信息所需内存大小
    );

2、得到所有的编码信息
  1. Status GetImageEncoders(  
  2.     UINT numEncoders,//可用编码器数量   
  3.     UINT size,//储存编码器信息所需内存(由ImageCodecInfo类组成的数组的大小)   
  4.     ImageCodecInfo* encoders//编码器信息指针   
  5.     );  
Status GetImageEncoders(
    UINT numEncoders,//可用编码器数量
    UINT size,//储存编码器信息所需内存(由ImageCodecInfo类组成的数组的大小)
    ImageCodecInfo* encoders//编码器信息指针
    );

在GetImageEncoders函数中,参数numEncoders和size都是由GetImageEncodersSize所返回的。下面的代码就能够在注册表中查找具体格式图像的编码方式:

  1. int GetImageCLSID(const WCHAR* format, CLSID* pCLSID)  
  2. {//得到格式为format的图像文件的编码值,访问该格式图像的COM组件的   
  3.     //GUID值保存在pCLSID中   
  4.     UINT num = 0;  
  5.     UINT size = 0;  
  6.     ImageCodecInfo* pImageCodecInfo = NULL;  
  7.     GetImageEncodersSize(&num, &size);  
  8.   
  9.     if(size == 0)  
  10.         return FALSE; // 编码信息不可用   
  11.   
  12.     //分配内存   
  13.     pImageCodecInfo = (ImageCodecInfo*)(malloc(size));  
  14.     if(pImageCodecInfo == NULL)  
  15.         return FALSE; // 分配失败   
  16.   
  17.     //获得系统中可用的编码方式的所有信息   
  18.     GetImageEncoders(num, size, pImageCodecInfo);  
  19.   
  20.     //在可用编码信息中查找format格式是否被支持   
  21.     for(UINT i = 0; i < num; ++i)  
  22.     { //MimeType:编码方式的具体描述   
  23.         if( wcscmp(pImageCodecInfo[i].MimeType, format) == 0 )  
  24.         {  
  25.             *pCLSID = pImageCodecInfo[i].Clsid;  
  26.             free(pImageCodecInfo);  
  27.             return TRUE;  
  28.         }  
  29.     }  
  30.     free(pImageCodecInfo);  
  31.     return FALSE;  
  32. }  
int GetImageCLSID(const WCHAR* format, CLSID* pCLSID)
{//得到格式为format的图像文件的编码值,访问该格式图像的COM组件的
    //GUID值保存在pCLSID中
    UINT num = 0;
    UINT size = 0;
    ImageCodecInfo* pImageCodecInfo = NULL;
    GetImageEncodersSize(&num, &size);

    if(size == 0)
        return FALSE; // 编码信息不可用

    //分配内存
    pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
    if(pImageCodecInfo == NULL)
        return FALSE; // 分配失败

    //获得系统中可用的编码方式的所有信息
    GetImageEncoders(num, size, pImageCodecInfo);

    //在可用编码信息中查找format格式是否被支持
    for(UINT i = 0; i < num; ++i)
    { //MimeType:编码方式的具体描述
        if( wcscmp(pImageCodecInfo[i].MimeType, format) == 0 )
        {
            *pCLSID = pImageCodecInfo[i].Clsid;
            free(pImageCodecInfo);
            return TRUE;
        }
    }
    free(pImageCodecInfo);
    return FALSE;
}

有了这种认识,实现多格式的图像的浏览与转换就并不是什么难事了。为了讲述的方便,首先在VC中建立一个SDI项目ImageShow,首先对使用GDI+申明和初始化及销毁进行代码编制,具体代码如下:

  1. #include "Gdiplus.h"   
  2. using namespace Gdiplus;  
  3.   
  4. CImageShowView::CImageShowView()  
  5. {  
  6.     //初始化GDI+   
  7.     GdiplusStartupInput gdiplusStartupInput;  
  8.     ULONG_PTR gdiplusToken;  
  9.     GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);  
  10. }  
  11.   
  12.   
  13. CImageShowView::~CImageShowView()  
  14. {  
  15.     //销毁GDI+   
  16.     ULONG_PTR gdiplusToken;  
  17.     GdiplusShutdown(gdiplusToken);  
  18. }  
#include "Gdiplus.h"
using namespace Gdiplus;

CImageShowView::CImageShowView()
{
    //初始化GDI+
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
}


CImageShowView::~CImageShowView()
{
    //销毁GDI+
    ULONG_PTR gdiplusToken;
    GdiplusShutdown(gdiplusToken);
}

接着通过类向导(Class Wizard),重载“文件”菜单中的“打开”和“另存为”两项,为了编程的简单,本程序只将当前打开的图像文件直接存为BMP文件(实际上保存成其他格式的文件也很简单,只不过是对文件名进行分析而已)进行文件名的传递,首先应在CImageShowView类中加入一全局变量“CString strOpenFileName”。“打开”和“另存为”两项的响应代码如下,大家通过代码中的注释部份理解编程思路,应该不会有什么问题:
  1. WCHAR* ToWChar(char * str)  
  2. {  
  3.     //在GDI+中,有关字符的参数类型全部都是WCHAR类型的   
  4.     //该函数是将传统字符串进行转换   
  5.     static WCHAR buffer[1024];  
  6.     wcsset(buffer,0);  
  7.     MultiByteToWideChar(CP_ACP,0,str,strlen(str),buffer,1024);  
  8.     return buffer;  
  9. }  
WCHAR* ToWChar(char * str)
{
    //在GDI+中,有关字符的参数类型全部都是WCHAR类型的
    //该函数是将传统字符串进行转换
    static WCHAR buffer[1024];
    wcsset(buffer,0);
    MultiByteToWideChar(CP_ACP,0,str,strlen(str),buffer,1024);
    return buffer;
}

  1. void CImageShowView::OnFileOpen()  
  2. {  
  3.     //本程序能够打开各类常见格式的图像文件   
  4.     static char szFilter[]="常见格式图形文件(*.*)|*.*|";  
  5.     CFileDialog dlgChoseImage(1,NULL,NULL,NULL,szFilter);  
  6.   
  7.     if(dlgChoseImage.DoModal()==IDOK)  
  8.     {  
  9.         strOpenFileName=dlgChoseImage.GetPathName();  
  10.         //打开文件后立即在窗口中显示(重绘客户窗口)   
  11.         this->Invalidate();  
  12.     }  
  13. }  
  14.   
  15.   
  16. void CImageShowView::OnFileSaveAs()  
  17. {  
  18.     if(strOpenFileName.IsEmpty())  
  19.     {  
  20.         AfxMessageBox("当前没有打开图像文件,不能进行保存!");  
  21.         return;  
  22.     }  
  23.   
  24.   
  25.     //建立图形对像   
  26.     Graphics graphics(GetDC()->m_hDC);  
  27.   
  28.     //装入当前已经打开的图形文件   
  29.     Image image(ToWChar(strOpenFileName.GetBuffer(strOpenFileName.GetLength())));  
  30.     CString strFileSave;  
  31.   
  32.     //当其他格式的图像全部另存为BMP文件   
  33.     static char szFilter[]="位图(*.BMP)|*.BMP|";  
  34.     CFileDialog dlgChoseImage(0,"BMP",NULL,NULL,szFilter);  
  35.     if(dlgChoseImage.DoModal()==IDOK)  
  36.     {  
  37.         strFileSave=dlgChoseImage.GetPathName();  
  38.         CLSID clsid;  
  39.   
  40.         if(GetImageCLSID(L"image/bmp", &clsid))  
  41.         {  
  42.             image.Save(ToWChar(strFileSave.GetBuffer(strFileSave.GetLength())), &clsid,NULL);  
  43.   
  44.             //将保存后的图像进行显示   
  45.             strOpenFileName=strFileSave;  
  46.             this->Invalidate();  
  47.         }  
  48.     }  
  49. }  
void CImageShowView::OnFileOpen()
{
    //本程序能够打开各类常见格式的图像文件
    static char szFilter[]="常见格式图形文件(*.*)|*.*|";
    CFileDialog dlgChoseImage(1,NULL,NULL,NULL,szFilter);

    if(dlgChoseImage.DoModal()==IDOK)
    {
        strOpenFileName=dlgChoseImage.GetPathName();
        //打开文件后立即在窗口中显示(重绘客户窗口)
        this->Invalidate();
    }
}


void CImageShowView::OnFileSaveAs()
{
    if(strOpenFileName.IsEmpty())
    {
        AfxMessageBox("当前没有打开图像文件,不能进行保存!");
        return;
    }


    //建立图形对像
    Graphics graphics(GetDC()->m_hDC);

    //装入当前已经打开的图形文件
    Image image(ToWChar(strOpenFileName.GetBuffer(strOpenFileName.GetLength())));
    CString strFileSave;

    //当其他格式的图像全部另存为BMP文件
    static char szFilter[]="位图(*.BMP)|*.BMP|";
    CFileDialog dlgChoseImage(0,"BMP",NULL,NULL,szFilter);
    if(dlgChoseImage.DoModal()==IDOK)
    {
        strFileSave=dlgChoseImage.GetPathName();
        CLSID clsid;

        if(GetImageCLSID(L"image/bmp", &clsid))
        {
            image.Save(ToWChar(strFileSave.GetBuffer(strFileSave.GetLength())), &clsid,NULL);

            //将保存后的图像进行显示
            strOpenFileName=strFileSave;
            this->Invalidate();
        }
    }
}

最后,为了显示浏览图像转换前后的效果,还应该在窗口中分另绘制转换前后的图像,这很容易,只需要在OnDraw函数中添加绘制代码,如下所述:
  1. void CImageShowView::OnDraw(CDC* pDC)  
  2. {  
  3.     CImageShowDoc* pDoc = GetDocument();  
  4.     ASSERT_VALID(pDoc);  
  5.     //如果没有选择显示图形文件,则不用重绘   
  6.     if(strOpenFileName.IsEmpty())  
  7.         return;  
  8.     //显示当前打开的图像文件的全名   
  9.     this->GetParent()->SetWindowText(strOpenFileName);  
  10.   
  11.     //建立图形对象   
  12.     Graphics graphics(pDC->m_hDC);  
  13.   
  14.     //装入图形文件   
  15.     Image image(ToWChar(strOpenFileName.GetBuffer(strOpenFileName.GetLength())));  
  16.     Point destPoints[3] =  
  17.     {  
  18.         Point(0, 0),  
  19.         Point(image.GetWidth(), 0),  
  20.         Point(0, image.GetHeight())  
  21.     };  
  22.     Point* pdestPoints = destPoints;  
  23.     //在指定区域pdestPoints显示图像   
  24.     graphics.DrawImage(&image, pdestPoints, 3);  
  25. }  
void CImageShowView::OnDraw(CDC* pDC)
{
    CImageShowDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    //如果没有选择显示图形文件,则不用重绘
    if(strOpenFileName.IsEmpty())
        return;
    //显示当前打开的图像文件的全名
    this->GetParent()->SetWindowText(strOpenFileName);

    //建立图形对象
    Graphics graphics(pDC->m_hDC);

    //装入图形文件
    Image image(ToWChar(strOpenFileName.GetBuffer(strOpenFileName.GetLength())));
    Point destPoints[3] =
    {
        Point(0, 0),
        Point(image.GetWidth(), 0),
        Point(0, image.GetHeight())
    };
    Point* pdestPoints = destPoints;
    //在指定区域pdestPoints显示图像
    graphics.DrawImage(&image, pdestPoints, 3);
}
在编译上面的程序之前,应该将Gdiplus.lib文件连编到项目中去,否则将会出现“LINK 2001”编译错误。该程序在Visual Studio 6.0、Windows2000/XP下调试通过,它能够显示或转换的图像格式有BMP、GIF、JPEG 、Exif 、PNG 、TIFF 、ICON、WMF 、EMF等等。需要说明的是,本文只就GDI+编程的基本原理进行阐述,其实,GDI+的应用远不止于此。在GDI+的背后,有你意想不到的惊奇!瞧,这程序运行起来是不是有些象ACDSee之类的图像浏览程序?如果对本程序进行些改进,你也以做出功能更加强劲的图像处理程序。本文中所提到的程序,在我的主页“国税之家”(http://nationaltax.home.chinaren.com)的“个人世界”中可以下下载到。有关GDI+的编程序帮助信息,大家可以到微软的MSDN网站去查阅。如果你有VisualStudio .NET,这就最好,因为所附的MSDN for Visual Studio.NET 7.0中有GDI+编程所需的全部信息
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值