當(dāng)前位置:首頁(yè) > 芯聞號(hào) > 充電吧
[導(dǎo)讀]這幾天放假在家無(wú)聊編一個(gè)程序,在加載png時(shí)遇到了麻煩,后來(lái)用了兩個(gè)方法解決了。一個(gè)是用GDI+,另外就是用vs.net MFC自帶的CImage。先看看GDI+的方法方法1:1.GDI+畫(huà)透明圖層

這幾天放假在家無(wú)聊編一個(gè)程序,在加載png時(shí)遇到了麻煩,后來(lái)用了兩個(gè)方法解決了。一個(gè)是用GDI+,另外就是用vs.net MFC自帶的CImage。

先看看GDI+的方法
方法1:

1.GDI+畫(huà)透明圖層(alpha)的png圖片


stdafx加入如下:


#include?//初始化一下com口
#include?"GdiPlus.h"
using?namespace?Gdiplus;
#pragma?comment(lib,"gdiplus.lib")



開(kāi)始初始化:
在app類的聲明里(.h)加入:


ULONG_PTR?m_gdiplusToken;



InitInstance()里加入://若沒(méi)有usingnamespace Gdiplus; 就要在前面加Gdiplus::



GdiplusStartupInput?gdiplusStartupInput;
GdiplusStartup(&m_gdiplusToken,?&gdiplusStartupInput,?NULL);



重載ExitInstance,加入GdiplusShutdown(m_gdiplusToken);


int?CxxxApp::ExitInstance()
{
	//?TODO:?在此添加專用代碼和/或調(diào)用基類
	GdiplusShutdown(m_gdiplusToken);
	return?CWinApp::ExitInstance();
}



顯示圖片的過(guò)程如下

CClientDC?*pDC?=?new?CClientDC(GetDlgItem(IDC_STATIC_PIC));
CRect?rect;
GetDlgItem(IDC_STATIC_PIC)->GetWindowRect(&rect);
Graphics?graphics(pDC->m_hDC);?//?Create?a?GDI+?graphics?object
Image?image(_T("1.png"));?//?Construct?an?image
graphics.DrawImage(&image,?0,?0,?image.GetWidth(),?image.GetHeight());
delete?pDC;


這是用GDI+來(lái)顯示圖片。


2.CImage繪制帶alpha透明圖層的png圖片 用MFC自帶的CImage也可以顯示,不過(guò)要稍微進(jìn)行轉(zhuǎn)換才能得到正常的帶α通道的png圖片! 在畫(huà)圖前進(jìn)行一次轉(zhuǎn)換,其中Image是CImage的對(duì)象

if?(Image.GetBPP()?==?32)?//確認(rèn)該圖像包含Alpha通道
{
	int?i;
	int?j;
	for?(i?=?0;?i?<?Image.GetWidth();?i++)
	{
		for?(j?=?0;?j?<?Image.GetHeight();?j++)
		{
			byte?*pByte?=?(byte?*)Image.GetPixelAddress(i,?j);
			pByte[0]?=?pByte[0]?*?pByte[3]?/?255;
			pByte[1]?=?pByte[1]?*?pByte[3]?/?255;
			pByte[2]?=?pByte[2]?*?pByte[3]?/?255;
		}
	}
}


具體方法如下:


HWND?hwnd?=?GetSafeHwnd();?//獲取窗口的HWND
::InvalidateRect(?hwnd,?NULL,?true?);?//或者?::InvalidateRect(?hwnd,?NULL,?false?);
::UpdateWindow(hwnd);
//若使用前不想把原來(lái)繪制的圖片去掉,可以刪去上面那三段
CDC?*pDC?=?GetDC();
CImage?Image;
Image.Load(strPath);
if?(Image.IsNull())
{
	MessageBox(_T("沒(méi)加載成功"));
	return?-1;
}
if?(Image.GetBPP()?==?32)?//確認(rèn)該圖像包含Alpha通道
{
	int?i;
	int?j;
	for?(i?=?0;?i?<?Image.GetWidth();?i++)
	{
		for?(j?=?0;?j?<?Image.GetHeight();?j++)
		{
			byte?*pByte?=?(byte?*)Image.GetPixelAddress(i,?j);
			pByte[0]?=?pByte[0]?*?pByte[3]?/?255;
			pByte[1]?=?pByte[1]?*?pByte[3]?/?255;
			pByte[2]?=?pByte[2]?*?pByte[3]?/?255;
		}
	}
}
Image.Draw(pDC->m_hDC,?0,?0);
Image.Destroy();
ReleaseDC(pDC);


代碼中內(nèi)部的框架是對(duì)圖像的再次處理,對(duì)原來(lái)進(jìn)行了修正,這樣得到的更加正常,代碼實(shí)測(cè)如下
繪圖后效果

為了方便,封裝成一個(gè)通用函數(shù): pWnd是需要顯示圖片的控件窗口,strPicPath是png圖片地址,bAutoFit是否需要自動(dòng)適應(yīng)pWnd的窗口

bool?ShowPNGInCtrl(CWnd*?pWnd,const?CString&?strPicPath,BOOL?bAutoFit)
{
	if?(NULL?==?pWnd)
	{
		return?false;
	}
	if?(NULL?==?pWnd->GetSafeHwnd())
	{
		return?false;
	}
	if?(strPicPath.GetLength()GetClientRect(rect);???
		HRESULT?hr;
		hr?=?img.Load(strPicPath);
		if?(S_OK?!=?hr)
		{
			return?false;
		}
		std::unique_ptrpDc;
		pDc.reset(new?CClientDC(pWnd));

		if?(bAutoFit)
		{
			if?(img.GetWidth()>img.GetHeight())//說(shuō)明圖片是長(zhǎng)方形
			{
				nDw??=?rect.Width();
				nDh??=?(int)(nDw?*?img.GetHeight()?/?img.GetWidth());
				nDPx?=?0;
				nDPy?=?(int)(rect.Height()/2.0?-?nDh/2.0);
				if?(nDh>rect.Height())//說(shuō)明圖片控件是橫著放,這時(shí)候就要再次縮減
				{
					nDh	?=rect.Height();
					nDw??=(int)(?img.GetWidth()*nDh/img.GetHeight());
					nDPy?=?0;
					nDPx?=(int)?(rect.Width()/2.0?-?nDw/2.0);
				}
			}
			else//說(shuō)明豎著比較明顯
			{
				nDh??=?rect.Height();
				nDw??=(int)(?img.GetWidth()*nDh/img.GetHeight());
				nDPy?=?0;
				nDPx?=(int)?(rect.Width()/2.0?-?nDw/2.0);
				if?(nDw>rect.Width())//說(shuō)明是另外一種情況
				{
					nDw??=?rect.Width();
					nDh??=?(int)(nDw?*?img.GetHeight()?/?img.GetWidth());
					nDPx?=?0;
					nDPy?=?(int)(rect.Height()/2.0?-?nDh/2.0);
				}
			}
		}
		else
		{
			nDw?=?img.GetWidth();
			nDh?=?img.GetHeight();
		}
		if?(img.GetBPP()?==?32)?//確認(rèn)該圖像包含Alpha通道
		{
			int?i;
			int?j;
			for?(i=0;?i<img.GetWidth();?i++)
			{
				for?(j=0;?jSetStretchBltMode(HALFTONE);
		img.Draw(pDc->m_hDC,nDPx,nDPy,nDw,nDh);
		//img.TransparentBlt(pDc->m_hDC,nDPx,nDPy,nDw,nDh,RGB(255,?255,?255));
	}
	catch?(...)
	{
		return?false;
	}
	return?true;
}





------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 3.如果圖片是在資源里的時(shí)候加載方法又不一樣
這時(shí)需要兩個(gè)函數(shù), 對(duì)于GDI+如下:

BOOL?ImageFromIDResource(UINT?nID,?LPCTSTR?sTR,Image?*&pImg)
{
	HINSTANCE?hInst?=?AfxGetResourceHandle();
	HRSRC?hRsrc?=?::FindResource?(hInst,MAKEINTRESOURCE(nID),sTR);?//?type
	if?(!hRsrc)
		return?FALSE;
	//?load?resource?into?memory
	DWORD?len?=?SizeofResource(hInst,?hRsrc);
	BYTE*?lpRsrc?=?(BYTE*)LoadResource(hInst,?hRsrc);
	if?(!lpRsrc)
		return?FALSE;
	//?Allocate?global?memory?on?which?to?create?stream
	HGLOBAL?m_hMem?=?GlobalAlloc(GMEM_FIXED,?len);
	BYTE*?pmem?=?(BYTE*)GlobalLock(m_hMem);
	memcpy(pmem,lpRsrc,len);
	GlobalUnlock(m_hMem);
	IStream*?pstm;
	CreateStreamOnHGlobal(m_hMem,FALSE,&pstm);
	//?load?from?stream
	pImg=Gdiplus::Image::FromStream(pstm);
	//?free/release?stuff
	pstm->Release();
	FreeResource(lpRsrc);
	GlobalFree(m_hMem);
	return?TRUE;
}



這時(shí)加載圖片的代碼變?yōu)椋?/p>

CClientDC?*pDC?=?new?CClientDC(GetDlgItem(IDC_STATIC_PIC));
CRect?rect;
GetDlgItem(IDC_STATIC_PIC)->GetWindowRect(&rect);
Graphics?graphics(pDC->m_hDC);?//?Create?a?GDI+?graphics?object
Image?*pimage;?//?Construct?an?image
ImageFromIDResource(IDB_PNG1,_T("PNG"),pimage);
graphics.DrawImage(pimage,?0,?0,pimage->GetWidth(),?pimage->GetHeight());
delete?pDC;



用CImage時(shí)需要如下函數(shù):

BOOL?LoadImageFromResource(CImage?*pImage,?UINT?nResID,LPCTSTR?lpTyp)
{
	if?(?pImage?==?NULL)?
		return?false;
	pImage->Destroy();
	//?查找資源
	HRSRC?hRsrc?=?::FindResource(AfxGetResourceHandle(),?MAKEINTRESOURCE(nResID),?lpTyp);
	if?(hRsrc?==?NULL)?
		return?false;
	//?加載資源
	HGLOBAL?hImgData?=?::LoadResource(AfxGetResourceHandle(),?hRsrc);
	if?(hImgData?==?NULL)
	{
		::FreeResource(hImgData);
		return?false;
	}
	//?鎖定內(nèi)存中的指定資源
	LPVOID?lpVoid?=?::LockResource(hImgData);
	LPSTREAM?pStream?=?NULL;
	DWORD?dwSize?=?::SizeofResource(AfxGetResourceHandle(),?hRsrc);
	HGLOBAL?hNew?=?::GlobalAlloc(GHND,?dwSize);
	LPBYTE?lpByte?=?(LPBYTE)::GlobalLock(hNew);
	::memcpy(lpByte,?lpVoid,?dwSize);
	//?解除內(nèi)存中的指定資源
	::GlobalUnlock(hNew);
	//?從指定內(nèi)存創(chuàng)建流對(duì)象
	HRESULT?ht?=?::CreateStreamOnHGlobal(hNew,?TRUE,?&pStream);
	if?(?ht?!=?S_OK?)
	{
		GlobalFree(hNew);
	}
	else
	{
		//?加載圖片
		pImage->Load(pStream);
		GlobalFree(hNew);
	}
	//?釋放資源
	::FreeResource(hImgData);
	return?true;
}



這時(shí)加載圖片的代碼如下:

HWND?hwnd?=?GetSafeHwnd();?//獲取窗口的HWND
::InvalidateRect(?hwnd,?NULL,?true?);?//或者?::InvalidateRect(?hwnd,?NULL,?false?);
::UpdateWindow(hwnd);?
CDC?*pDC?=?GetDC();
CImage?Image;
LoadImageFromResource(&Image,IDB_PNG1,_T("PNG"));
if?(Image.IsNull())
{
	MessageBox(_T("沒(méi)加載成功"));
	return;
}
if?(Image.GetBPP()?==?32)?//確認(rèn)該圖像包含Alpha通道
{?
	int?i;
	int?j;
	for?(i=0;?i<Image.GetWidth();?i++)
	{
		for?(j=0;?jm_hDC,0,0);
Image.Destroy();
ReleaseDC(pDC);




另 要注意的是,最好把繪圖放在OnPaint消息響應(yīng)里,否則,OnSize消息觸發(fā)OnPaint重繪時(shí)可能會(huì)把之前的繪圖全部清除

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開(kāi)發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開(kāi)幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉