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

sep*_*ang 43 c#

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

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

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

kDa*_*Dar 94

这里尽可能快速而干净.通过使用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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

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

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

  • 好方案!物业检查很重要.如果你添加if(myImage.PropertyIdList.Any(x => x == 36867))作为你的支票它很棒! (7认同)
  • 稍微揭开这个答案的神秘面纱。PropertyItem 36867(或十六进制的 0x9003)是 MSDN 中描述的“PropertyTagExifDTOrig”列表 http://msdn.microsoft.com/en-us/library/system.drawing.imaging.propertyitem.id(v=vs. 110).aspx (5认同)
  • 现在,只有你已经检查过它是否存在.这家酒店总有可能没有. (4认同)
  • 它向我显示错误"无法找到属性".我试图处理.PNG文件 (2认同)
  • 如果有人想让它在 Unity 中运行,请在主驱动器中搜索“System.Drawing.dll”并将该文件复制到您的 Assets 文件夹中。现在添加对“using System.Text;”的引用 使用系统绘图;使用 System.Drawing.Imaging;` (2认同)

sep*_*ang 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);
Run Code Online (Sandbox Code Playgroud)

  • 实际上,306 是最后一个修改的日期标识符......我试过,它非常接近......但是,查看所有属性 ID,并转储到文本文件,我发现 ID 36867 是拍摄日期(尽管 36868也有相同的 Date Taken 值,所以我不确定哪个是哪个) (3认同)

Dre*_*kes 8

自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);
Run Code Online (Sandbox Code Playgroud)

在我的基准测试中,此代码运行Image.GetPropertyItem速度比WPF JpegBitmapDecoder/ BitmapMetadataAPI 快12倍,并且快了约17倍.

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

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

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

var directories = JpegMetadataReader.ReadMetadata(stream, new[] { new ExifReader() });
Run Code Online (Sandbox Code Playgroud)

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


Dav*_*veK 5

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

MSDN - BitmapMetada

WPF和BitmapMetadata