2014-02-27 43 views
4

我想獲得給定圖像中所有EXIF標籤的列表。 使用Image.propertyItems[]數組,我可以枚舉圖像對象實例讀取的所有項目,並輸出其ID。並非所有的圖像屬性檢索Image.PropertyItems

我看到那裏沒有列出的項目,其他應用程序,包括Windows資源管理器似乎沒有問題檢索。

E.G.下面的代碼...

Image img = new Bitmap("C:\\IMAG0648.jpg"); 
foreach (PropertyItem property in img.PropertyItems) 
    { 
    Trace.WriteLine(property.Id); 
    } 

我得到的最項目的上市,特別是雖然我失蹤(其中可能還有其他)的0x010F0x0110。我知道這些項目那裏,因爲我可以在另一個像PhotoME這樣的EXIF編輯器中打開相同的圖像,並且它們顯然存在,並且清楚地標記爲正確的ID。

EXIF中是否有嵌套層次,我沒有走得太遠,或者是否有某些原因使得它在上面的基本形式中不起作用?

回答

2

嘗試ExifLib - 沒有與源,它可以提取,你可以使用一個像所有標籤演示項目。

編輯:我要追加我的答案來解釋爲什麼我相信.Net Image類不能像我們所期望的那樣處理所有EXIF標籤。不過,我會在上面留下我的初步鏈接和建議,因爲我相信這是最終的最佳選擇。

好了,到爲什麼

的文件下使用的圖像,其中Windows 7中顯示EXIF數據,品牌和型號的描述我的測試(點擊右鍵>屬性>「詳細資料」選項卡>「相機」部分),但在.Net中,PropertyItems不包含這些相同的EXIF標記。在另一個答案中提到了使用HTC One拍攝的圖像,因此我找到了符合我的測試here的圖像。 (具體來說,我從這個網頁使用了original-2.jpg,original-4.jpg和original-8.jpg)。

首先,我看着img.PropertyItems.Count()得到了32.所以裏面有數據! (顯然,我們知道Windows 7在我的情況下是看到EXIF標籤)。但是,當我遍歷.PropertyItems,並在每個Id看(按你原來的問題):

  • 我得到32個結果
  • 我不明白造成271(0x010F - 相機品牌)的ID或272 (0x0110 - 相機型號)
  • 我沒有得到282,283,296,305,306等27點5位數的ID
  • 如果我使用img.PropertyItems.Single(x => x.Id == 305).Value我得到了SoftwareUsed(或者,如果我使用206我得到的日期時間)EXIF屬性

那麼,就你而言,爲什麼.Net Image類沒有看到帶有271/272的Ids(再次,Camera Make/Model)的EXIF標籤?

我挖成ExifLib的源代碼(鏈接答案的頂部)一點點,覺得我看到發生了什麼:

  • 如果您在ExifReader.cs看private byte[] GetTagBytes(...)方法(線655),你將看到字節偏移量用於查找'Exif IDF'和每個標記的總空間
  • 此方法返回一個特定的字節數組,然後將其轉換爲正確的數據類型
  • 如果該類型是ASCII字符串 - 空字符被刪除並且日期格式被調整

因此,看起來.Net Image類能夠通過PropertyItems正確地返回EXIF標記,當有不是任何字節偏移在播放。

使用ExifDataView(http://www.nirsoft.net/utils/exif_data_view.html)我能證實這一點:

  • 我發現我總是能夠使用.NET來正確地獲取品牌和型號,當值長度爲4(「HTC」 +空字符)
  • 從來能夠使用的.Net時長爲5(「HTC」 +空+空?)
  • 在我的測試上面(與原-4.JPG圖) SoftwareUsed和DateTime標籤因爲這些標籤的長度而起作用(字符串長度)+1表示空字符。 Camera Make標籤長度爲(字符串長度)+ 2,並且不起作用。這似乎把一切都拋開了。

ExifLib代碼可以正確處理這些偏移和/或多個空字符,而.Net不會。

結果是.NET圖片類不超過這些特性的PropertyItems部分迭代和返回使用image.PropertyItems.Single(x => x.Id == tagMake).Value

底線當「序列不包含匹配元件」:使用ExifLib或一些其它第三第三方庫設計用於處理提取EXIF數據,如果你想讓它適用於所有圖像。使用.Net Image類,如果你希望它的某些時間字節是正確的:-)

+0

我已經看過其他解決方案,那是其中之一,我很欣賞這些輸入,其中之一可能最終成爲我最終使用的解決方案。然而,這樣做的目的是爲了理解爲什麼.NET圖像類正在跳過這些項目,而其他人似乎選擇了它們。對我來說,在這個階段它代表我的錯誤或誤解,因爲雖然它是特定於圖像源的,但其他軟件產品似乎沒有問題。 – Sabre

+0

這位先生,正是我所尋找的,對本地.NET類的解決方案或可驗證的缺乏支持。非常感謝! – Sabre

1

根據the documentation,您指定的標籤肯定存在。這是爲我工作與this sample image

Sample image with EXIF metadata

int tagMake = 0x010F; // 271 
int tagModel = 0x0110; // 272 

Image image = Image.FromFile(@"C:\image.jpg"); 

byte[] make = image.PropertyItems.Single(x => x.Id == tagMake).Value; 
byte[] model = image.PropertyItems.Single(x => x.Id == tagModel).Value; 

var encoding = new System.Text.ASCIIEncoding(); 

Console.WriteLine(encoding.GetString(make)); // Returns: Canon 
Console.WriteLine(encoding.GetString(model)); // Returns: Canon PowerShot S40 
+0

非常奇怪,如果我運行我的和你的代碼對* *圖像,我得到的標籤,從我的HTC一個智能手機的一個我從他們兩個代碼都沒有得到他們。諸如ExifTool之類的東西在兩張圖片上都顯示了它們,並且它們都報告爲EXIF v2.2,因此我認爲它們都具有相同的格式。我可以接受一個損壞的圖像,但所有與我的HTC和我妻子的Note3一起拍攝的圖像都具有無法在.NET中看到此問題的相同問題,但可以在任何其他編輯器中使用。那麼,哪些方面甚至可以開始更深入的建議? – Sabre

+0

@Sabre雖然你可以嘗試第三方的命令行工具。或者,您可以嘗試列出'image.PropertyItems'中的所有屬性,並查看您正在查找的屬性是否使用不同的ID。 – sshow

+0

我已經完成了這兩個,這是問題的一部分。所有的第三方工具在那裏顯示標籤,並且具有相同的ID。 Image.PropertyItems []不會在這些照片上顯示這些標籤。代碼*會從其他圖像讀取這些標籤。所以我想了解爲什麼其他程序可以看到它們,但.NET不能在相同的圖像上?除.net以外的每個編輯器/查看器*其他*都可以毫無問題地提取出來,我可以在十六進制編輯器中清楚地看到它們。另外,能夠在其他圖像中看到正確的標籤可以讓我相信代碼是正確的...... – Sabre

相關問題