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

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

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

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


stdafx加入如下:


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



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


ULONG_PTR?m_gdiplusToken;



InitInstance()里加入://若沒有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();
}



顯示圖片的過程如下

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+來顯示圖片。


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

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);
//若使用前不想把原來繪制的圖片去掉,可以刪去上面那三段
CDC?*pDC?=?GetDC();
CImage?Image;
Image.Load(strPath);
if?(Image.IsNull())
{
	MessageBox(_T("沒加載成功"));
	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)部的框架是對圖像的再次處理,對原來進行了修正,這樣得到的更加正常,代碼實測如下
繪圖后效果

為了方便,封裝成一個通用函數(shù): pWnd是需要顯示圖片的控件窗口,strPicPath是png圖片地址,bAutoFit是否需要自動適應(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())//說明圖片是長方形
			{
				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())//說明圖片控件是橫著放,這時候就要再次縮減
				{
					nDh	?=rect.Height();
					nDw??=(int)(?img.GetWidth()*nDh/img.GetHeight());
					nDPy?=?0;
					nDPx?=(int)?(rect.Width()/2.0?-?nDw/2.0);
				}
			}
			else//說明豎著比較明顯
			{
				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())//說明是另外一種情況
				{
					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ù), 對于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;
}



這時加載圖片的代碼變?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ù):

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)建流對象
	HRESULT?ht?=?::CreateStreamOnHGlobal(hNew,?TRUE,?&pStream);
	if?(?ht?!=?S_OK?)
	{
		GlobalFree(hNew);
	}
	else
	{
		//?加載圖片
		pImage->Load(pStream);
		GlobalFree(hNew);
	}
	//?釋放資源
	::FreeResource(hImgData);
	return?true;
}



這時加載圖片的代碼如下:

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("沒加載成功"));
	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重繪時可能會把之前的繪圖全部清除

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

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

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

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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