日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

【windows gdi+】GDI+ Image类加载图片时异常问题处理与分析

發布時間:2025/3/15 windows 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【windows gdi+】GDI+ Image类加载图片时异常问题处理与分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題描述:

項目里一個控件,需要加載本地圖片,單張第一次加載的時候可以的,但是重新選擇其他圖片,會出現圖片顯示異常的現象。

直接上圖,圖片部分顯示不全了。

問題分析:

一開始懷疑現象是有個圖片重復選擇后顯示是好的,其他某幾個圖很容易復現,就懷疑是圖片問題,查了半天jpg圖片完整性,發現圖片也沒什么區別,后面又查分辨率,在DrawImage()里修改分辨率為偶數了也不行。。。最后只能看代碼了,發現是代碼里自己清理GLOBAL內存了。其實之前有項目我遇到清理GLOBAL內存導致圖片顯示不全或者異常的問題。時間太久忘記了。還是記錄一下吧。

知識附錄:


1, 是Bitmap(RT_BITMAP)類型的圖片無法加載, RT_BITMAP是預定義類型, 資源里面沒有bmp文件的頭,?SizeofResource 的返回值要比圖片文件少幾個字節,因為少了這幾個字節, 所以GDI+會返回invalid parameter錯誤。

2, 從IStream里面創建出來的Image對象會引用到堆里面的GLOBAL內存, 如果GLOBAL內存hBuffer被釋放了, 創建的Image的內容就會被破壞,有時只能畫出一小部分圖片, 有時整個圖片有大片的亂碼,好像是編碼失敗的樣子, 視當時的內存狀況而定。

另外調用Image的Clone也沒用,深層次想Clone不是真正的深拷貝,還是依賴那個GLOBAL內存的,如果那個內存被銷毀了,Clone的圖片也會異常。

只有在銷毀或者析構的時候才能清理那個GLOBAL內存,否則會導致顯示異常(不是100%出現,而是間歇性出現,但是肯定會出現)。

這是看到的demo,拷貝過來的,可以看看,注意看注釋。

?CYourClass::~CYourClass() {for(IMG_VECTOR::iterator?it?=?m_arImage.begin();?it?!=?m_arImage.end();?it++)delete?*it;for(HGLB_VECTOR::iterator?it?=?m_arGlobal.begin();?it?!=?m_arGlobal.end();?it++){::GlobalUnlock(*it);::GlobalFree(*it);} }void?CYourClass::AddImage(HMODULE?hInst,?UINT?nResourceID,?LPCTSTR?lpType) {if(lpType?==?RT_BITMAP){//GDI+?can?not?load?RT_BITMAP?resouce,?//because?they?are?predefined?resource,?//they?don't?contains?the?image?file?header.assert(FALSE);return;}HRSRC?hResource?=?::FindResource(hInst,?MAKEINTRESOURCE(nResourceID),?lpType);if?(!hResource)return;DWORD?imageSize?=?::SizeofResource(hInst,?hResource);if?(!imageSize)return;const?void*?pResourceData?=?::LockResource(::LoadResource(hInst,?hResource));if?(!pResourceData)return;HGLOBAL?hBuffer?=?::GlobalAlloc(GMEM_FIXED,?imageSize);if?(NULL?==?hBuffer)return;void*?pBuffer?=?::GlobalLock(hBuffer);if?(pBuffer){CopyMemory(pBuffer,?pResourceData,?imageSize);IStream*?pStream?=?NULL;if?(::CreateStreamOnHGlobal(hBuffer,?FALSE,?&pStream)?==?S_OK){Gdiplus::Image?*?pImage?=?Gdiplus::Image::FromStream(pStream);pStream->Release();if?(pImage){?if?(pImage->GetLastStatus()?==?Gdiplus::Ok?&&pImage->GetWidth()?>?0){m_arImage.push_back(pImage);//it?seems?the?image?will?take?usage?of?the?global?memory.//so?the?global?memory?should?be?kept?until?the?image?destroy.//GDI++此種打開本地文件的方式占用了這片內存,只有在你銷毀圖片時才能銷毀這片 //內存,否則會破壞你的圖片,導致顯示異常m_arGlobal.push_back(hBuffer);return;}delete?pImage;}}::GlobalUnlock(hBuffer);}::GlobalFree(hBuffer); }?

總結

以上是生活随笔為你收集整理的【windows gdi+】GDI+ Image类加载图片时异常问题处理与分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。