六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

VC完成多格式圖像的轉(zhuǎn)換

[摘要]◆ 周鳴揚(yáng) (healthboy@163.net) 色彩鮮艷漂亮的高品質(zhì)圖像,一個(gè)個(gè)形象生動(dòng)的Windows圖標(biāo),高速運(yùn)動(dòng)、活靈活現(xiàn)的三維動(dòng)畫,這些無一不顯示出程序設(shè)計(jì)者的藝術(shù)才華。在程序設(shè)計(jì)中,圖像處理已經(jīng)成為每個(gè)程序員的必修課。 在VC中編程顯示一幅位圖,下列步驟是不可缺少的: 裝入位圖、獲得...
◆ 周鳴揚(yáng) (healthboy@163.net)

色彩鮮艷漂亮的高品質(zhì)圖像,一個(gè)個(gè)形象生動(dòng)的Windows圖標(biāo),高速運(yùn)動(dòng)、活靈活現(xiàn)的三維動(dòng)畫,這些無一不顯示出程序設(shè)計(jì)者的藝術(shù)才華。在程序設(shè)計(jì)中,圖像處理已經(jīng)成為每個(gè)程序員的必修課。

在VC中編程顯示一幅位圖,下列步驟是不可缺少的: 裝入位圖、獲得位圖的大小信息、啟用設(shè)備環(huán)境、位傳輸?shù)龋璧某绦虼a一般比較冗長而且復(fù)雜。如果想將裝入的位圖另存為其他格式的圖像文件,代碼就更長了。這一切都是因?yàn)镚DI本身的局限性造成的。

GDI+技術(shù)

隨著Windows 2000的推出,上述情況有了極大的改觀: 程序員不必了解每種圖像格式的具體含義,照樣可以寫出多格式圖像瀏覽或轉(zhuǎn)換程序,這一切全都依賴于Windows 2000及后繼版中所使用的GDI+技術(shù)。

和傳統(tǒng)的GDI不同,GDI+中引入了對(duì)COM(組件對(duì)象模型)技術(shù)的支持,通過COM技術(shù),GDI+簡化了對(duì)圖像文件的訪問(打開、保存)。它是通過調(diào)用COM組件來實(shí)現(xiàn)的,GDI+扮演的只是指揮者,而非操作員。對(duì)于圖像文件,GDI+所關(guān)心的不是圖像文件的文件頭信息,不論要打開的文件格式是什么類型,GDI+首先要做的是在注冊(cè)表中查看該圖像格式的編碼(或解碼)信息是否已經(jīng)注冊(cè)(HKEY_CLASSES_ROOT\MIME\Database\Content Type)。如果已經(jīng)注冊(cè),就通過該編碼信息調(diào)用COM組件,就這么簡單。這種技術(shù)早就在微軟的其他軟件中使用了(如IE)。“體驗(yàn)”過Nimda病毒的朋友可能對(duì)“audio/wav”這段代碼并不陌生,Nimda就是靠它來偽裝自己的:讓IE認(rèn)為附件是WAV文件而自動(dòng)打開可執(zhí)行程序,這其實(shí)也是IE使用COM技術(shù)的一個(gè)突出表現(xiàn)。

配合GDI+的推出,微軟也同時(shí)發(fā)布了相應(yīng)的SDK,如果已經(jīng)安裝了最新的Microsoft PlatForm SDK或已經(jīng)開始使用VS.NET,GDI+的SDK就已經(jīng)在系統(tǒng)中了。如果沒有的話,可以到http: //noner.top263.net/progtool上去下載GDI+的頭文件和庫文件。有了GDI+之后,只需簡單地創(chuàng)建一個(gè)圖形對(duì)象(Graphics object),然后直接調(diào)用該對(duì)象的方法(methods)進(jìn)行繪圖即可。圖形對(duì)象是GDI+中的核心,正如DC之于GDI那樣。圖形對(duì)象和DC有許多相似的地方,在使用上遵循著相同的使用規(guī)則,但是兩者在本質(zhì)上已經(jīng)有很大的區(qū)別。一個(gè)是基于句柄的GDI,一個(gè)是基于組件對(duì)象模型的GDI+。使用GDI+的SDK編程,必須按照下面的規(guī)范來進(jìn)行:使用GDI+的命名空間(namespace Gdiplus),在使用GDI+函數(shù)時(shí)必須進(jìn)行GDI+的初始化,使用完畢要銷毀GDI+,這些規(guī)范在下面所列的程序中有詳細(xì)的說明。

訪問注冊(cè)表編碼信息

上面說到GDI+是通過在注冊(cè)表中查看編碼信息來訪問圖像文件的,在GDI+的SDK中,編碼信息是存儲(chǔ)在 ImageCodecInfo類中的,在這個(gè)類中,有編碼的CLSID(COM組件的GUID標(biāo)識(shí)碼)、編碼方式描述等。對(duì)于GDI,在注冊(cè)表中訪問編碼信息通常使用以下兩個(gè)函數(shù)來實(shí)現(xiàn):

1. 查看系統(tǒng)中可用的圖像編碼信息(數(shù)量及大小)

Status GetImageEncodersSize(

UINT* numEncoders,

//存儲(chǔ)編碼器數(shù)量的地址

UINT* size //存儲(chǔ)編碼信息所需內(nèi)存大小

);

2. 得到所有的編碼信息

Status GetImageEncoders(

UINT numEncoders,//可用編碼器數(shù)量

UINT size,//存儲(chǔ)編碼器信息所需內(nèi)存(由ImageCodecInfo類組成的數(shù)組的大小)

ImageCodecInfo* encoders//編碼器信息指針

);

在GetImageEncoders函數(shù)中,參數(shù)numEncoders和size都是由GetImageEncodersSize返回的。下面的代碼在注冊(cè)表中查找具體格式圖像的編碼方式:

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; // 編碼信息不可用

//分配內(nèi)存

pImageCodecInfo = (ImageCodecInfo*)(malloc(size));

if(pImageCodecInfo == NULL)

return FALSE; // 分配失敗

//獲得系統(tǒng)中可用的編碼方式的所有信息

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;

}

實(shí)現(xiàn)多格式的圖像瀏覽和轉(zhuǎn)換

有了前面的知識(shí),實(shí)現(xiàn)多格式的圖像的瀏覽與轉(zhuǎn)換就不是什么難事了。

1.在VC中創(chuàng)建一個(gè)SDI項(xiàng)目ImageShow,對(duì)GDI+聲明和初始化及銷毀進(jìn)行代碼編制,具體代碼如下:

#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);

}

2. 通過類向?qū)?Class Wizard),重載“文件”菜單中的“打開”和“另存為”兩項(xiàng)。為了編程的簡單,本程序只將當(dāng)前打開的圖像文件直接存為BMP文件(實(shí)際上保存為其他格式的文件也很簡單,只不過是對(duì)文件名進(jìn)行分析而已)。另外,為了在打開和保存文件時(shí)進(jìn)行文件名的傳遞,還應(yīng)在CImageShowView類中加入一全局變量“CString strOpenFileName”。“打開”和“另存為”兩菜單的對(duì)應(yīng)代碼如下:

WCHAR* ToWChar(char * str)

{

//在GDI+中,有關(guān)字符的參數(shù)類型全部都是WCHAR類型

//該函數(shù)是將傳統(tǒng)字符串進(jìn)行轉(zhuǎn)換

static WCHAR buffer[1024];

wcsset(buffer,0);

MultiByteToWideChar(CP_ACP,0,str,strlen(str),buffer,1024);

return buffer;

}

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(“當(dāng)前沒有打開圖像文件,不能進(jìn)行保存!”);

return;

}

//建立圖形對(duì)象

Graphics graphics(GetDC()->m_hDC);

//裝入當(dāng)前已經(jīng)打開的圖像文件

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);

//將保存后的圖像進(jìn)行顯示

strOpenFileName=strFileSave;

this->Invalidate();

}

}

}

3.為了瀏覽圖像轉(zhuǎn)換前后的效果,還應(yīng)該在窗口中分別繪制轉(zhuǎn)換前后的圖像,這需要在OnDraw函數(shù)中添加繪制代碼,如下所示:

void CImageShowView::OnDraw(CDC* pDC)

{

CImageShowDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

//如果沒有選擇顯示圖像文件,則不用重繪

if(strOpenFileName.IsEmpty())

return;

//顯示當(dāng)前打開的圖像文件的全名

this->GetParent()->SetWindowText(strOpenFileName);

//建立圖像對(duì)象

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;

//在指定區(qū)域pdestPoints顯示圖像

graphics.DrawImage(&image, pdestPoints, 3);

}

在編譯上面的程序之前,應(yīng)該將Gdiplus.lib文件連編到項(xiàng)目中去,否則將會(huì)出現(xiàn)“LINK 2001”編譯錯(cuò)誤。上述程序在Visual Studio 6.0、Windows 2000/XP下調(diào)試通過,它能夠顯示或轉(zhuǎn)換的圖像格式有BMP、GIF、JPEG、Exif、PNG、TIFF、ICON、WMF、EMF等等。需要說明的是,本文只就GDI+編程的基本原理進(jìn)行了闡述,事實(shí)上,GDI+的應(yīng)用遠(yuǎn)不止此。

結(jié)束語

如果對(duì)本程序進(jìn)行些改進(jìn),還可以編制出功能更加強(qiáng)大的圖像處理程序。本文中所提到的程序,在筆者的主頁“國稅之家”(http://nationaltax.home.chinaren.com)的“個(gè)人世界”中可以下載到。有關(guān)GDI+編程的幫助信息,大家可以到微軟的MSDN網(wǎng)站去查閱。


主站蜘蛛池模板: 亚洲最新网址 | 亚洲图区欧美 | 亚欧乱色一区二区三区 | 日本综合在线观看 | 欧美怡红院免费的视频 | 日本视频在线免费观看 | 在线污污视污免费 | 日日淫| 四虎8848永久在线 | 欧美一级黄色录像片 | 在线bt在线www天堂网在线 | 天天躁夜夜躁狠狠躁20216 | 日韩 欧美 亚洲 | 人人婷婷色综合五月第四人色阁 | 最近新韩国日本免费看 | 日本高清视频网址 | 日韩精品导航 | 欧美又粗又大又硬又长又爽视频 | 亚洲欧美成人 | 五月婷婷色播 | 亚洲天堂在线观看完整版 | 日韩精品一区二区三区不卡 | 日韩中文有码高清 | 日韩精品a在线视频 | 日本一二三区在线视频 | 日皮毛片| 天天插天天狠天天透 | 婷婷久月 | 亚洲免费在线 | 日本一区二区在线免费观看 | 宇都宫紫苑日韩专区亚洲 | 我要看黄色毛片 | 日韩精品一区二区三区毛片 | 欧美一级做一级爱a做片性 欧美一级做一a做片性视频 | 色wwwwww| 四川一级护士一级毛片 | 婷婷综合激六月情网 | 日日射夜夜操 | 天堂亚洲网 | 任我爽精品视频在线播放 | 午夜影院普通用户体验区 |