2011-09-16 58 views
4

DLL文件包含PNG資源類型中的一些圖像。從.NET的本機Win32資源獲取PNG圖像

我可以使用Resource Hacker,Anolis Resourcer & Resource Tuner等軟件查看PNG圖像。檢查安樂Resourcer的這個截圖瞭解詳情:

http://i51.tinypic.com/9pt93c.jpg

誰能告訴我如何獲取PNG圖像沒有。 5220從DLL文件,並將其放入一個PictureBox?我不認爲像LoadImage或LoadBitmap API會工作。

+0

它是一個嵌入式的資源或者是一個資源文件? – casperOne

回答

6
// get the assembly containing the image 
var assembly = Assembly.GetExecutingAssembly(); 

// set the picturebox image to read the embedded resource 
pictureBox1.Image = Image.FromStream(
    assembly.GetManifestResourceStream("AssemblyName.test.png") 
); 

其中AssemblyName.test.png是程序集內嵌入資源的完全限定名稱。


UPDATE:

看來你正試圖從一個本地裝配提取資源。你可以看看following article,它說明了如何使用P/Invoke完成這個工作。

+0

@AnonMouse,那是什麼? –

+0

@AnnonMouse,這是一個託管程序集或原生? –

+0

@AnonMouse,好的,我已經更新了我的答案,並附上了一篇文章鏈接,說明如何實現這一目標。 –

3

PNG圖像不是標準的Win32資源類型之一。它通常嵌入爲指定資源類型「PNG」的二進制blob,儘管這不是保證。到目前爲止,最簡單的方法是使用Visual Studio的File + Open + File命令打開文件。找到資源後,右鍵單擊它並選擇導出將其保存到磁盤。

以編程方式進行此操作需要大量的砂礫針。這很棘手,因爲資源類型和資源ID都可以是字符串或IntPtr,因此您需要爲FindResource重新創建4個重載。爲了便於使用LoadLibraryEx()來加載文件而不執行任何代碼。 FindResource獲取資源的句柄。 SizeOfResource知道它有多大。 LoadResource + LockResource獲取指向資源數據的指針。 Marshal.Copy()將資源數據複製到一個字節[]中。使用FreeResource和FreeLibrary進行清理。

4

Darin發佈的鏈接(因此被標記爲答案)不包含功能代碼。我評估了發佈在那裏的代碼(http://khason.net/blog/how-to-load-unmanaged-native-resources-from-managed-c-code/),發現它無法正常工作嵌入在任何win32 dll中的位圖圖像作爲位圖資源。

此外,漢斯帕斯坦離開了無數的步驟有效地使他的職位無用。

我已經能夠找到的唯一稍微接近的解決方案來自於2004年爲XP主題dll垃圾編寫的文章。你可以在這裏找到ThemeManager.cs http://www.codeproject.com/KB/miscctrl/XPTaskBar.aspx

然而,「GetResourcePNG」的方法,但應注意的是,我已經有很多困難的用這種方法,因爲調用bitmap.RotateFlip(RotateFlipType.Rotate180FlipX) ;

我發現這裏列出的代碼(http://www.vbaccelerator.com/home/NET/:我的系統

更新上authui.dll內試圖訪問PNG圖像時會導致內存問題Code/Controls/Explorer_Bar/ExplorerBar_Control_Source_Code.asp)功能最強大,產生最少的錯誤併產生最快的結果。該代碼是用C#編寫的,即使域名會另外指出。使用這兩個類; ImageUtility和ResourceLibrary,您可以輕鬆地拉出來PNG標準的,non-.net資源庫/ DLL:

public static Bitmap GetStandardResourceBitmap(String dllName, String resourceId) { 
     Bitmap result = null; 

     using (ResourceLibrary library = new ResourceLibrary() { Filename = dllName }) { 
      IntPtr hDib = library.GetResource(resourceId, ResourceLibrary.ImageType.IMAGE_BITMAP, ResourceLibrary.ImageLoadOptions.LR_CREATEDIBSECTION); 
      if (!hDib.Equals(IntPtr.Zero)) { 
       result = ImageUtility.DibToBitmap(hDib); 
       ImageUtility.DeleteObject(hDib); 
      } 
     } 

     return result; 
    } 

我選擇了有RESOURCEID在我的方法的字符串,不僅是因爲它不需要過載和使用編號的資源ID就像添加一個'#'一樣簡單。

GetStandardResourceBitmap("shell32.dll", "#632"); 

乾杯

+0

我沒有錯過任何東西 - 你沒有讀完整個線程。他發佈的代碼不適用於win32 dll內的資源,也不是代碼鏈接到標準win32 dll資源的功能 - 這正是作者的目標。如果你閱讀整篇文章,你會發現這一點。對於標準dll中的非PNG位圖資源,Bitmap.FromResource是要使用的方法。但是,未列在「PNG」資源類型中的PNG存在其他問題,如我鏈接的代碼中概述的那樣。 – shellscape