2008-10-07 10 views
36

विंडोज एक्सपी में "FileInfo.LastWriteTime" एक तस्वीर ली गई तारीख को वापस कर देगा - इस पर ध्यान दिए बिना कि फाइल सिस्टम में फ़ाइल कितनी बार स्थानांतरित हो जाती है।Vista पर चल रहे सी # में वास्तव में एक तस्वीर कब ली गई थी, तो मुझे कैसे पता चलेगा?

Vista में यह उस तारीख को लौटाता है जब तस्वीर कैमरे से कॉपी की जाती है।

Vista में एक तस्वीर लेने पर मुझे कैसे पता चलेगा? विंडोज एक्सप्लोरर में इस फ़ील्ड को "डेट ले लिया गया" कहा जाता है।

उत्तर

78

यहां जितना तेज़ और साफ हो सकता है उतना ही आप इसे प्राप्त कर सकते हैं। FileStream का उपयोग करके, आप GDI + को सत्यापन के लिए पूरी छवि लोड न करने के लिए कह सकते हैं। यह मेरी मशीन पर तेजी से 10x से अधिक चलाता है।

//we init this once so that if the function is repeatedly called 
    //it isn't stressing the garbage man 
    private static Regex r = new Regex(":"); 

    //retrieves the datetime WITHOUT loading the whole image 
    public static DateTime GetDateTakenFromImage(string path) 
    { 
     using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) 
     using (Image myImage = Image.FromStream(fs, false, false)) 
     { 
      PropertyItem propItem = myImage.GetPropertyItem(36867); 
      string dateTaken = r.Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2); 
      return DateTime.Parse(dateTaken); 
     } 
    } 

और 36867 हाँ, सही आईडी है, 306

नहीं अन्य मुक्त स्रोत नीचे परियोजनाओं इस पर ध्यान देना चाहिए। हजारों फाइलों को संसाधित करते समय यह एक बड़ा perfprmance हिट है!

+1

कुछ परीक्षणों के बाद मुझे पता चला कि आपका उत्तर सबसे अच्छा है। धन्यवाद। – Sergio

+4

अब केवल अगर आप यह जांचने के लिए चेक करते हैं कि यह पहले मौजूद है या नहीं। यह संपत्ति हमेशा एक मौका नहीं है। –

+6

ग्रेट सॉल्यूशन! संपत्ति की जांच महत्वपूर्ण है। यदि आप जोड़ते हैं (myImage.PropertyIdList.Any (x => x == 36867)) आपकी जांच के रूप में यह बहुत अच्छा काम करता है! –

5
WPF और सी # के साथ

आप की तिथि संपत्ति BitmapMetadata वर्ग का उपयोग कर प्राप्त कर सकते हैं:

MSDN - BitmapMetada

WPF and BitmapMetadata

+0

क्या मैं बिटमैप मेटाडेटा विंडो के साथ उपयोग कर सकता हूं। फर्म या क्या यह केवल WPF है? (विजुअल स्टूडियो 2008 से अजीब त्रुटि संदेश प्राप्त करना) – sepang

+0

या [मेरी लाइब्रेरी] (http://stackoverflow.com/a/39839380/24874) का उपयोग करें जिसमें एक सरल API है और इन WPF API (या 30) से लगभग 17 गुना तेज चलता है यदि आप केवल Exif चाहते हैं तो तेजी से समय)। –

1

आप चित्र से EXIF ​​जानकारी की जाँच करना होगा। मैं नियमित रूप से नहीं सोचता। नेट फ़ंक्शन आपको पता चल जाएगा कि तस्वीर कब ली गई थी।

यह थोड़ा जटिल हो सकती है ...

1

छवि में एम्बेडेड EXIF ​​डेटा नहीं किया जाएगा। यदि आप EXIF ​​और C# की खोज करते हैं तो वेब पर उदाहरणों का एक टन है। भले ही कितनी बार फ़ाइल फाइल सिस्टम में चारों ओर ले जाया जाता है की -

2

Windows XP "FileInfo.LastWriteTime" में तारीख वापस आ जाएगी एक तस्वीर लिया है।

मुझे बहुत संदेह है कि XP ​​वास्तव में ऐसा कर रहा था। अधिक संभावना है कि आप कैमरे से छवि को कॉपी करने के लिए उपयोग की जाने वाली टूल को हार्ड डिस्क फ़ाइल संशोधित दिनांक को छवि की तारीख में रीसेट कर रहे थे।

+0

उपकरण विंडोज एक्सप्लोरर था। – sepang

+0

आह .. यह समझा सकता है। कैमरा एक फाइल सिस्टम के साथ एक छोटा कंप्यूटर है। जब फोटो लिया जाता है तो यह "डिस्क पर लिखा जाता है"। जब एक्सप्लोर किया जाता है तो एक्सप्लोरर उनको बनाए रखता है –

10
Image myImage = Image.FromFile(@"C:\temp\IMG_0325.JPG"); 
PropertyItem propItem = myImage.GetPropertyItem(306); 
DateTime dtaken; 

//Convert date taken metadata to a DateTime object 
string sdate = Encoding.UTF8.GetString(propItem.Value).Trim(); 
string secondhalf = sdate.Substring(sdate.IndexOf(" "), (sdate.Length - sdate.IndexOf(" "))); 
string firsthalf = sdate.Substring(0, 10); 
firsthalf = firsthalf.Replace(":", "-"); 
sdate = firsthalf + secondhalf; 
dtaken = DateTime.Parse(sdate); 
+1

असल में, 306 अंतिम संशोधित दिनांक पहचानकर्ता है ... मैंने कोशिश की और यह बहुत बंद था ... हालांकि, सभी संपत्ति आईडी देखकर, और एक टेक्स्ट फ़ाइल में डंपिंग, मैंने पाया कि आईडी 36867 तारीख ले ली गई थी (हालांकि 36868 में भी वैल्यू ले लिया गया वैल्यू है, इसलिए मैं सकारात्मक नहीं हूं जो कि था) – DRapp

+0

ऊपर दिए गए उत्तर को उत्तर में बदल दिया जाना चाहिए, अगर यह मौजूद है तो EXIFG प्राप्त करने की गति। यह विधि काम करती है, लेकिन धीमी है - खासकर बैच में! – TheSoftwareJedi

0
//retrieves the datetime WITHOUT loading the whole image 
    public static DateTime GetDateTakenFromImage(string path) 
    { 
     using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) 
     using (Image myImage = Image.FromStream(fs, false, false)) 
     { 
      PropertyItem propItem = null; 
      try 
      { 
       propItem = myImage.GetPropertyItem(36867); 
      } 
      catch { } 
      if (propItem != null) 
      { 
       string dateTaken = r.Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2); 
       return DateTime.Parse(dateTaken); 
      } 
      else 
       return new FileInfo(path).LastWriteTime; 
     } 
    } 
+0

यह सचमुच @ kDar के उत्तर का एक डुप्लिकेट है, जिसमें थोड़ा सा त्रुटि हैंडलिंग ... – Mark

4

मैंने 2002 से छवि/वीडियो फ़ाइलों से मेटाडेटा निकालने के लिए simple open-source library बनाए रखा।

// Read all metadata from the image 
var directories = ImageMetadataReader.ReadMetadata(stream); 

// Find the so-called Exif "SubIFD" (which may be null) 
var subIfdDirectory = directories.OfType<ExifSubIfdDirectory>().FirstOrDefault(); 

// Read the DateTime tag value 
var dateTime = subIfdDirectory?.GetDateTime(ExifDirectoryBase.TagDateTimeOriginal); 

मेरी मानक में, इस कोड बार 12 से अधिक Image.GetPropertyItem तुलना में तेजी से चलाता है, और लगभग 17 बार WPF JpegBitmapDecoder/BitmapMetadata एपीआई की तुलना में तेजी।

लाइब्रेरी से उपलब्ध अतिरिक्त जानकारी का एक टन है जैसे कैमरा सेटिंग्स (एफ-स्टॉप, आईएसओ, शटर गति, फ्लैश मोड, फोकल लम्बाई, ...), छवि गुण (आयाम, पिक्सेल कॉन्फ़िगरेशन) और अन्य चीजें जैसे जीपीएस पदों, कीवर्ड, कॉपीराइट जानकारी, आदि

यदि आप केवल मेटाडेटा में रूचि रखते हैं, तो इस लाइब्रेरी का उपयोग करना बहुत तेज है क्योंकि यह छवि (यानी बिटमैप) को डीकोड नहीं करता है।यदि आपके पास पर्याप्त संग्रहण है तो आप कुछ सेकंड में हजारों छवियों को स्कैन कर सकते हैं।

ImageMetadataReader कई फाइल प्रकारों (जेपीईजी, पीएनजी, जीआईएफ, बीएमपी, टीआईएफएफ, पीसीएक्स, वेबपी, आईसीओ, ...) को समझता है। आप कि आप जेपीईजी साथ काम कर रहे पता , और आप केवल Exif डेटा चाहते हैं, तो आप इस प्रक्रिया भी तेजी से निम्नलिखित के साथ कर सकते हैं:

var directories = JpegMetadataReader.ReadMetadata(stream, new[] { new ExifReader() }); 

मेटाडाटा-निकालने पुस्तकालय उपलब्ध है NuGet और code's on GitHub के माध्यम से। उन सभी अद्भुत योगदानकर्ताओं के लिए धन्यवाद जिन्होंने लाइब्रेरी में सुधार किया है और वर्षों में टेस्ट छवियां जमा की हैं।

+0

ड्रू, मैं वापस आ गया हूँ! अब मेरे पास रॉ को टिफ में बदलने के लिए कोड है लेकिन मेरी छवि। गेटप्रॉपर्टी इटिम की 36867 का उपयोग करके तारीख नहीं है। क्या आपका कोड टिफ और रॉ करता है? – JustJohn

+0

और। । । । ड्रम रोल। । । । यह आपके Nugetter के अनुसार निर्दोष रूप से स्थापित किया गया है और अपने एवर में उपरोक्त कोड का उपयोग करके यह एक सीआर 2 फ़ाइल (कैनन) के लिए फोटो लेने की तिथि लौटा दी! बेशक, शीर्ष पर उपयोग करने के लिए कई संभावित सुधारों पर क्लिक करना पड़ा लेकिन वीएस 2017 आपको बेबीसिट करता है। – JustJohn

+0

यह सुनकर खुशी हुई कि यह आपके लिए काम करता है। –

संबंधित मुद्दे