2008-10-07 2 views
36

Windows XP에서 "FileInfo.LastWriteTime"은 파일 시스템에서 파일을 몇 번 이동했는지에 관계없이 사진을 찍은 날짜를 반환합니다.Vista에서 실행되는 C#으로 사진을 실제로 찍은 시간은 어떻게 알 수 있습니까?

Vista에서는 대신 사진이 카메라에서 복사 된 날짜를 반환합니다.

Vista에서 사진을 찍을 때 어떻게 알 수 있습니까? Windows 탐색기에서이 필드를 "가져온 날짜"라고합니다. WPF와 C#으로

답변

78

최대한 빠르고 깨끗합니다. FileStream을 사용하면 GDI +가 확인을 위해 전체 이미지를로드하지 않도록 지정할 수 있습니다. 그것은 내 컴퓨터에서 10 배 이상 빠르게 실행됩니다. 아래의 다른 오픈 소스 프로젝트는이 주목을해야하지 306

//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); 
     } 
    } 

그리고 네, 올바른 ID는 36867. 수천 개의 파일을 처리 할 때 큰 피해가 발생합니다!

+1

몇 가지 테스트를 마친 후 가장 좋은 답변을 찾았습니다. 감사. – Sergio

+4

이제는 먼저 존재하는지 확인해야합니다. 이 속성은 항상 그렇지 않습니다. –

+6

그레이트 솔루션! 속성 검사가 중요합니다. 수표로 if (myImage.PropertyIdList.Any (x => x == 36867))를 추가하면 멋지게 작동합니다! –

5

당신이 BitmapMetadata 클래스를 사용하여 날짜 촬영 재산 얻을 수 있습니다 :

MSDN - BitmapMetada

WPF and BitmapMetadata

+0

Window.Forms에서 BitmapMetadata를 사용할 수 있습니까? 아니면 WPF 만 사용할 수 있습니까? (Visual Studio 2008에서 이상한 오류 메시지가 표시됨) – sepang

+0

또는 API가 간단한 [WPF API (또는 30 개)보다 약 17 배 빠른 [내 라이브러리] (http://stackoverflow.com/a/39839380/24874) Exif 만 원할 경우 시간이 더 빠름). –

1

당신이 사진의 EXIF ​​정보를 확인해야합니다. 정기적 인 .Net 함수로는 사진을 찍을 때 알 수 없다고 생각합니다.

다소 복잡 할 수도 있습니다 ...

1

이미지에 EXIF ​​데이터가 삽입됩니다. EXIF와 C#을 검색하면 웹에 많은 예제가 있습니다. 에 관계없이 파일이 파일 시스템에서 주변에 이동 횟수 의 - 날짜에게 그림을 반환합니다 윈도우 XP "FileInfo.LastWriteTime"에서

2

는 촬영입니다.

저는 실제로 XP에서 그렇게하고있었습니다. 카메라의 이미지를 하드 디스크에 복사하는 데 사용한 도구가 File Modified Date를 이미지의 촬영 날짜로 다시 설정하는 경우 일 수 있습니다.

+0

도구는 Windows 탐색기입니다. – sepang

+0

아 .. 그걸 설명 할 수 있어요. 카메라는 파일 시스템이있는 소형 컴퓨터입니다. 사진을 찍을 때 "디스크에 기록"됩니다. Explorer는 복사 할 때이를 유지합니다. –

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은 마지막으로 수정 한 날짜 식별자입니다 ... 시도했는데 매우 닫았습니다 ... 그러나 모든 속성 ID를보고 텍스트 파일로 덤핑하면 ID 36867이 36868도 같은 Date Daken 값을 가지고 있으므로 어떤 것이 었는지는 확실하지 않습니다. – 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); 

,이 코드는 약 17 배 빠른 WPF JpegBitmapDecoder/BitmapMetadata API보다 더 Image.GetPropertyItem에 비해 12 배 이상 빠르게 실행합니다.

카메라 설정 (F- 스톱, ISO, 셔터 속도, 플래시 모드, 초점 거리 등), 이미지 속성 (크기, 픽셀 구성) 및 기타 사항과 같이 라이브러리에서 사용할 수있는 추가 정보가 있습니다 (GPS 위치, 키워드, 저작권 정보 등)

메타 데이터에만 관심이있는 경우이 라이브러리를 사용하면 이미지 (예 : 비트 맵)를 디코딩하지 않으므로 매우 빠릅니다.저장 공간이 충분하면 몇 초 안에 수천 개의 이미지를 스캔 할 수 있습니다.

ImageMetadataReader은 많은 파일 형식 (JPEG, PNG, GIF, BMP, TIFF, PCX, WebP, ICO 등)을 인식합니다. 당신은 당신이 JPEG 상대하고을 알고 , 당신은 Exif 데이터를 원하는 경우에, 당신은 다음과 같이 더 빠른 프로세스를 만들 수 있습니다

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

메타 데이터 추출 라이브러리를 사용할 수 NuGetcode's on GitHub을 통해 도서관을 개선하고 수년에 걸쳐 시험 이미지를 제출 한 놀라운 기여자 덕분입니다.

+0

드류, 저 돌아 왔어요! 나는 이제 Tiff로 RAW를 변환하는 코드를 가지고 있지만 Image.GetPropertyItem에는 36867을 사용하여 찍은 날짜가 없습니다. 코드가 Tiffs 및 Raws를 사용합니까? – JustJohn

+0

그리고. . . . 드럼 롤. . . . 당신의 Nugetter 당 완벽하게 설치하고 당신의 anwer에서 위의 코드를 사용하여 .CR2 파일 (Canon)의 photoTaken 날짜를 반환했습니다! 물론, 몇 가지 잠재적 인 수정 프로그램을 사용하여 상단에 넣어지만 VS 2017 베이비 시터를 클릭했다. – JustJohn

+0

다행히 듣고 다행스럽게 생각합니다. –

관련 문제