陳敏++林金表
摘要:在VC++中要實(shí)現(xiàn)常用圖像格式之間的轉(zhuǎn)換,通常需要掌握每種圖像格式的文件頭格式、調(diào)色板、圖像壓縮算法等具體細(xì)節(jié),實(shí)現(xiàn)過程復(fù)雜。運(yùn)用GDI+技術(shù),無需了解每種圖像格式的具體含義,即可實(shí)現(xiàn)常用圖像格式間的轉(zhuǎn)換,并且可以將簡(jiǎn)單幾何轉(zhuǎn)換后的圖像保存在任意目錄下。
關(guān)鍵詞:GDI+;圖像格式轉(zhuǎn)換;幾何變換
DOIDOI:10.11907/rjdk.143701
中圖分類號(hào):TP317.4
文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào)文章編號(hào):16727800(2015)001014102
0 引言
圖像是人類獲取信息的主要途徑之一,在研究圖像處理過程中,實(shí)現(xiàn)常用圖像文件格式的相互轉(zhuǎn)換符合現(xiàn)實(shí)需求。例如實(shí)現(xiàn)常用格式圖片BMP與GIF的相互轉(zhuǎn)換,首先需要對(duì)BMP和GIF文件格式進(jìn)行分析,然后才能實(shí)現(xiàn)二者之間的讀取與顯示等相關(guān)操作[1]。GDI(Graphics Device Interface:圖形設(shè)備接口), 是Windows提供給應(yīng)用程序的編程接口[2]。GDI+是基于類的應(yīng)用程序編程接口[3]。GDI+是在GDI的基礎(chǔ)上發(fā)展起來的,增加了許多新功能。
GDI+中引用了對(duì)COM(組件對(duì)象模型)技術(shù)的支持,通過COM技術(shù),開發(fā)人員在輸出屏幕和打印機(jī)信息時(shí)無需考慮顯示設(shè)備的細(xì)節(jié),只需要調(diào)用GDI+庫(kù)輸出類的一些方法即可完成繪圖工作 [4],GDI+簡(jiǎn)化了圖像文件訪問程序[5]。隨著GDI+的升級(jí),功能也隨之變得更加強(qiáng)大,如幾何轉(zhuǎn)換、Alpha blending、紋理、貼圖、增強(qiáng)的文本及圖像顯示技術(shù)[6]等,極大方便了開發(fā)人員在圖形、圖像領(lǐng)域的開發(fā)應(yīng)用,使圖像處理工作變得相對(duì)簡(jiǎn)單。
1 基于GDI+的多種格式圖像轉(zhuǎn)換
1.1 GDI+庫(kù)初始化
在調(diào)用GDI+函數(shù)之前,需要調(diào)用GDI+庫(kù)的初始化函數(shù)GdiplusStartup來初始化GDI+庫(kù),GdiplusStartup的原型如下:
Status GdiplusStartup( _out ULONG_PTR token *token,_in const GdiplusStartupInput *input,_out GdiplusStartupOutput *output);
GdiplusStartup (&m_pGdiToken, &m_gdiplusStartupInput, NULL)函數(shù)&m_pGdiToken是存儲(chǔ)地址,記錄了此次使用GDI+的標(biāo)記;&m_gdiplusStartupInput包含GDI +版本,是指向調(diào)試回調(diào)函數(shù)的指針,以及用于指定是否支持后臺(tái)線程和外來的圖像編碼等信息;output是指向GdiplusStartupOutput 類型數(shù)據(jù)的一個(gè)指針,初始化結(jié)束時(shí),初始化函數(shù)GdiplusStartup在GdiplusStartupOutput類型數(shù)據(jù)中存放一個(gè)事件鉤子函數(shù)指針和卸載事件鉤子函數(shù)指針;NULL表示SuppressBackgroundThread的數(shù)據(jù)成員錯(cuò)誤時(shí)即為空。
結(jié)束后使用GdiplusShutdown()函數(shù)關(guān)閉GDI+。
1.2 圖像顯示
(1)查看系統(tǒng)可用編碼器信息。用已安裝圖像編碼器的程序段,尋找格式為format的圖像編碼器類型標(biāo)識(shí)碼CLSID,并保存在pCLSID中,成功返回true,否則就返回false。GetImageCLSID得到格式為format的圖像文件編碼值和訪問該格式圖像COM組件的GUID值,保存在pCLSID中。在可用編碼信息中查找是否支持format格式的編碼值,函數(shù)原型為:
Int GetImageCLSID(const WCHAR *format, CLSID *pCLSID)
為了得到所有編碼器信息、編碼器數(shù)量、儲(chǔ)存編碼器信息所需要的內(nèi)存等,可以調(diào)用函數(shù)GetImageEncoders()。該函數(shù)可讓用戶知道,在GDI+的情況下哪些圖像編譯信息是可用的,函數(shù)GetImageEncoders的原型是:
Status GetImageEncoders (UINT unmEncoders,UINT size,ImageCodecInfo *encoders);
在GDI+的Image類封裝了對(duì)BMP、GIF、JPEG、PNG、TIFF、WMF(Windows元文件)和EMF(增強(qiáng)WMF)圖像文件的調(diào)入、格式轉(zhuǎn)換以及簡(jiǎn)單處理功能。在Image類從外設(shè)轉(zhuǎn)入圖像與內(nèi)存中時(shí)需要圖像編碼器(ImageEncoders)的幫助。圖像編碼器(ImageEncoders)和圖像解碼器(ImageDecoders)是與特定的圖像格式相聯(lián)系的,也就是說不同格式的圖像有不同的圖像編碼器和圖像解碼器。
(2)圖像文件讀取。在GDI+中顯示圖像文件轉(zhuǎn)入到內(nèi)存并顯示,首先要?jiǎng)?chuàng)建一個(gè)Image對(duì)象,然后調(diào)用FileOpen()打開各類常用格式的圖像文件,szFilter[]="常用圖像格式文件(*.*)|*.*|";在MFC ClassWixard中重載OnFileOpen() Static char szFilter[]="位圖文件(*.bmp;*.dib)|*.bmp;*.dib|JPG文件(*.jpg)|*.jpg|JPEG文件(*.jpeg)|*.jpeg|GIF文件(*.gif)|*.gif|PNG文件(*.png)|*.png|All Files(*.*)|*.*||";
CfileDialog CFileDialog dlgChoseImage(1,NULL,NULL,NULL,szFilter)
運(yùn)行上述程序可以打開任意目錄下任何常用格式圖片。
1.3 圖像格式轉(zhuǎn)換
將打開的圖像文件保存,定義一個(gè)函數(shù)StroeBitmap (CString cs)來存儲(chǔ)圖像旋轉(zhuǎn)后的位圖。
BITMAP bitmp;
HBITMAP hbitmap=(HBITMAP)GetCurrentObject(memDC,OBJ_BITMAP);
GetObject(hbitmap,sizeof(bitmp),(void *)&bitmp);
BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bi;
打開圖像位圖文件的存儲(chǔ)地址,調(diào)用FileSave() 對(duì)旋轉(zhuǎn)圖像進(jìn)行保存,可以保存為任意常用格式的圖片,可以隨時(shí)選擇保存的圖像格式:
Image Image(ToWChar(strOpenFileName.GetBuffer(strOpenFileName.GetLength())));
Cstring strFileSave;
Static char szFilter =” "位圖文件(*.bmp;*.dib)|*.bmp;*.dib|JPEG文件(*.jpeg;*.jpg)|*.jpeg;*.jpg|GIF文件(*.gif)|*.gif|PNG文件(*.png)|*.png|All Files(*.*)|*.*||";
CFileDialog dlgChoseImage(0,”BMP”,未命名,NULL,szFilter);
Image.Save(ToWChar(strFileSave.GetBuffer(strFileSave.GetLength()) &clsid,NULL);
將轉(zhuǎn)換后的圖片存到指定目錄,定義圖像名稱。
2 圖像幾何轉(zhuǎn)換
GDI+提供函數(shù)OnDraw(CDC* pDC),可繪制圖形或顯示圖形,改變圖像顯示的位置,任意拉伸圖像的大小,任意旋轉(zhuǎn)圖像,代碼如下:
Image
image(ToWChar(strOpenFileName.GetBuffer(strOpenFileName.GetLength())));
Point destPoints[3] =
{
Point(0,0),
Point(800,0),
Point(0, image.GetWidth())
};
Point* pdestPoints = destPoints;
graphics.DrawImage(&image, pdestPoints, 3);
::BitBlt(pDC->m_hDC,0,0,image.GetWidth(),image.GetHeight(),memDC,0,0,SRCCOPY);
::DeleteObject(memBM);
用CreateCompatibleBitmap(API函數(shù))來創(chuàng)建一幅與指定設(shè)備環(huán)境相關(guān)的設(shè)備兼容位圖。用CreateCompatibleBitmap將旋轉(zhuǎn)后的圖像位圖保存。
memDC=::CreateCompatibleDC(pDC ->m_hDC);
HBITMAPmemBM=(HBITMAP)::CreateCompatibleBitmap(pDC->m_hDC,image.GetHeight(),image.GetWidth());
::SelectObject(memDC,memBM);
打開原圖,將JPG轉(zhuǎn)換成BMP,經(jīng)過幾何變換后,得到如圖1所示的效果。
圖1 幾何變換效果
3 結(jié)語
GDI+是一種優(yōu)秀的圖形圖像處理技術(shù)。本文的程序是在Windows 系統(tǒng)Microsoft Visual Studio 2010下基
于GDI+調(diào)試通過的,它能夠打開BMP、GIF、JPEG、PNG、TIFF,WMF和EMF等任意常用格式圖像,可以任意幾何變換顯示和保存,如旋轉(zhuǎn)、拉伸、縮放等;可以轉(zhuǎn)換成任意常用圖像格式,并保存在任意目錄下。
參考文獻(xiàn):
[1] 韓嬌.基于VC++的BMP格式圖像與GIF格式圖像的相互轉(zhuǎn)換[J].武漢理工大學(xué)學(xué)報(bào),2007,12(29):2325.
[2] 李睿敏,陳俐坊.基于GDI+技術(shù)圖形圖像處理[J].紡織機(jī)械,2013(4):3033.
[3] 周鳴揚(yáng),曾潔玫. GDI+程序設(shè)計(jì)實(shí)例[M].北京:中國(guó)水利水電出版社,2004.
[4] 劉濤. 基于Visual C++6.0的GDI+圖像編程[J].中文信息,2003(11):8789.
[5] 劉海硯,安曉亞. 基于GDI+的圖像快速處理[C]//北京:中國(guó)地理信息系統(tǒng)協(xié)會(huì)第四次會(huì)員代表大會(huì)暨第十一屆年會(huì)論文集,2007:204209.
[6] 劉燕麗.GDI+在圖形學(xué)教學(xué)的研究與應(yīng)用[J].軟件導(dǎo)報(bào),2011,4(10):111120.