如何在Vista上运行C#时实时拍摄照片?

时间:2022-02-25 16:06:02

In windows XP "FileInfo.LastWriteTime" will return the date a picture is taken - regardless of how many times the file is moved around in the filesystem.

在Windows XP中,“FileInfo.LastWriteTime”将返回拍摄照片的日期 - 无论文件在文件系统中移动多少次。

In Vista it instead returns the date that the picture is copied from the camera.

在Vista中,它会返回从相机复制图片的日期。

How can I find out when a picture is taken in Vista? In windows explorer this field is referred to as "Date Taken".

如何在Vista中拍摄照片?在Windows资源管理器中,此字段称为“采取日期”。

8 个解决方案

#1


88  

Here's as fast and clean as you can get it. By using FileStream, you can tell GDI+ not to load the whole image for verification. It runs over 10x as fast on my machine.

这里尽可能快速而干净。通过使用FileStream,您可以告诉GDI +不要加载整个图像以进行验证。它在我的机器上运行速度超过10倍。

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

And yes, the correct id is 36867, not 306.

是的,正确的ID是36867,而不是306。

The other open source projects below should take note of this. it is a HUGE perfprmance hit when processing thousands of files!

下面的其他开源项目应该注意到这一点。处理数千个文件时,这是一个巨大的性能!

#2


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

#3


6  

I maintained a simple open-source library since 2002 for extracting metadata from image/video files.

自2002年以来,我维护了一个简单的开源库,用于从图像/视频文件中提取元数据。

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

In my benchmarks, this code runs over 12 times faster than Image.GetPropertyItem, and around 17 times faster than the WPF JpegBitmapDecoder/BitmapMetadata API.

在我的基准测试中,此代码的运行速度比Image.GetPropertyItem快12倍,比WPF JpegBitmapDecoder / BitmapMetadata API快17倍。

There's a tonne of extra information available from the library such as camera settings (F-stop, ISO, shutter speed, flash mode, focal length, ...), image properties (dimensions, pixel configurations) and other things such as GPS positions, keywords, copyright info, etc.

图书馆提供了大量额外信息,例如相机设置(F-stop,ISO,快门速度,闪光模式,焦距......),图像属性(尺寸,像素配置)以及其他诸如GPS位置等信息,关键字,版权信息等

If you're only interested in the metadata, then using this library is very fast as it doesn't decode the image (i.e. bitmap). You can scan thousands of images in a few seconds if you have fast enough storage.

如果您只对元数据感兴趣,那么使用此库非常快,因为它不解码图像(即位图)。如果您有足够快的存储空间,您可以在几秒钟内扫描数千张图像。

ImageMetadataReader understands many files types (JPEG, PNG, GIF, BMP, TIFF, PCX, WebP, ICO, ...). If you know that you're dealing with JPEG, and you only want Exif data, then you can make the process even faster with the following:

ImageMetadataReader了解许多文件类型(JPEG,PNG,GIF,BMP,TIFF,PCX,WebP,ICO ......)。如果您知道自己正在使用JPEG,并且只需要Exif数据,那么您可以使用以下内容更快地完成此过程:

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

The metadata-extractor library is available via NuGet and the code's on GitHub. Thanks to all the amazing contributors who have improved the library and submitted test images over the years.

元数据提取器库可通过NuGet获得,代码可以在GitHub上获得。感谢所有令人惊叹的贡献者,他们多年来改进了图书馆并提交了测试图像。

#4


5  

With WPF and C# you can get the Date Taken property using the BitmapMetadata class:

使用WPF和C#,您可以使用BitmapMetadata类获取Date Taken属性:

MSDN - BitmapMetada

MSDN - BitmapMetada

WPF and BitmapMetadata

WPF和BitmapMetadata

#5


2  

In windows XP "FileInfo.LastWriteTime" will return the date a picture is taken - regardless of how many times the file is moved around in the filesystem.

在Windows XP中,“FileInfo.LastWriteTime”将返回拍摄照片的日期 - 无论文件在文件系统中移动多少次。

I have great doubts XP was actually doing that. More likely the tool you used to copy the image from the camera to you hard disk was reseting the File Modified Date to the image's Date Taken.

我非常怀疑XP实际上是这么做的。您用于将图像从相机复制到硬盘的工具更可能是将文件修改日期重置为图像的拍摄日期。

#6


1  

you'll have to check the EXIF information from the picture. I don't think with regular .Net functions you'll know when the picture was taken.

你必须检查图片中的EXIF信息。我不认为使用常规的.Net功能,你会在拍摄照片时知道。

It might get a little complicated...

它可能会有点复杂......

#7


1  

There will be EXIF data embedded in the image. There are a ton of examples on the web if you search for EXIF and C#.

图像中将嵌入EXIF数据。如果您搜索EXIF和C#,网上会有大量示例。

#8


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

#1


88  

Here's as fast and clean as you can get it. By using FileStream, you can tell GDI+ not to load the whole image for verification. It runs over 10x as fast on my machine.

这里尽可能快速而干净。通过使用FileStream,您可以告诉GDI +不要加载整个图像以进行验证。它在我的机器上运行速度超过10倍。

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

And yes, the correct id is 36867, not 306.

是的,正确的ID是36867,而不是306。

The other open source projects below should take note of this. it is a HUGE perfprmance hit when processing thousands of files!

下面的其他开源项目应该注意到这一点。处理数千个文件时,这是一个巨大的性能!

#2


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

#3


6  

I maintained a simple open-source library since 2002 for extracting metadata from image/video files.

自2002年以来,我维护了一个简单的开源库,用于从图像/视频文件中提取元数据。

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

In my benchmarks, this code runs over 12 times faster than Image.GetPropertyItem, and around 17 times faster than the WPF JpegBitmapDecoder/BitmapMetadata API.

在我的基准测试中,此代码的运行速度比Image.GetPropertyItem快12倍,比WPF JpegBitmapDecoder / BitmapMetadata API快17倍。

There's a tonne of extra information available from the library such as camera settings (F-stop, ISO, shutter speed, flash mode, focal length, ...), image properties (dimensions, pixel configurations) and other things such as GPS positions, keywords, copyright info, etc.

图书馆提供了大量额外信息,例如相机设置(F-stop,ISO,快门速度,闪光模式,焦距......),图像属性(尺寸,像素配置)以及其他诸如GPS位置等信息,关键字,版权信息等

If you're only interested in the metadata, then using this library is very fast as it doesn't decode the image (i.e. bitmap). You can scan thousands of images in a few seconds if you have fast enough storage.

如果您只对元数据感兴趣,那么使用此库非常快,因为它不解码图像(即位图)。如果您有足够快的存储空间,您可以在几秒钟内扫描数千张图像。

ImageMetadataReader understands many files types (JPEG, PNG, GIF, BMP, TIFF, PCX, WebP, ICO, ...). If you know that you're dealing with JPEG, and you only want Exif data, then you can make the process even faster with the following:

ImageMetadataReader了解许多文件类型(JPEG,PNG,GIF,BMP,TIFF,PCX,WebP,ICO ......)。如果您知道自己正在使用JPEG,并且只需要Exif数据,那么您可以使用以下内容更快地完成此过程:

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

The metadata-extractor library is available via NuGet and the code's on GitHub. Thanks to all the amazing contributors who have improved the library and submitted test images over the years.

元数据提取器库可通过NuGet获得,代码可以在GitHub上获得。感谢所有令人惊叹的贡献者,他们多年来改进了图书馆并提交了测试图像。

#4


5  

With WPF and C# you can get the Date Taken property using the BitmapMetadata class:

使用WPF和C#,您可以使用BitmapMetadata类获取Date Taken属性:

MSDN - BitmapMetada

MSDN - BitmapMetada

WPF and BitmapMetadata

WPF和BitmapMetadata

#5


2  

In windows XP "FileInfo.LastWriteTime" will return the date a picture is taken - regardless of how many times the file is moved around in the filesystem.

在Windows XP中,“FileInfo.LastWriteTime”将返回拍摄照片的日期 - 无论文件在文件系统中移动多少次。

I have great doubts XP was actually doing that. More likely the tool you used to copy the image from the camera to you hard disk was reseting the File Modified Date to the image's Date Taken.

我非常怀疑XP实际上是这么做的。您用于将图像从相机复制到硬盘的工具更可能是将文件修改日期重置为图像的拍摄日期。

#6


1  

you'll have to check the EXIF information from the picture. I don't think with regular .Net functions you'll know when the picture was taken.

你必须检查图片中的EXIF信息。我不认为使用常规的.Net功能,你会在拍摄照片时知道。

It might get a little complicated...

它可能会有点复杂......

#7


1  

There will be EXIF data embedded in the image. There are a ton of examples on the web if you search for EXIF and C#.

图像中将嵌入EXIF数据。如果您搜索EXIF和C#,网上会有大量示例。

#8


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