1

我想从 jpg 图像中提取 exif 数据。ExifLib似乎是简化这项工作的好选择,因此我通过 NuGet 安装了它。

然后我尝试开始使用此处的示例代码(现在注释掉 MessageBox 代码):

using (ExifReader reader = new ExifReader(@"C:\temp\testImage.jpg"))
{
    // Extract the tag data using the ExifTags enumeration
    DateTime datePictureTaken;
    if (reader.GetTagValue<DateTime>(ExifTags.DateTimeDigitized, out datePictureTaken))
    {
        // Do whatever is required with the extracted information
        //System.Windows.MessageBox.Show(this, string.Format("The picture was taken on {0}",
        //   datePictureTaken), "Image information"); //, MessageBoxButtons.OK);
    }
}

但得到一个错误:

'ExifLib.ExifReader.ExifReader(System.IO.Stream)' 的最佳重载方法匹配有一些无效参数

参数 1:无法从 'string' 转换为 'System.IO.Stream'

都在这条线上:

using (ExifReader reader = new ExifReader(@"C:\temp\testImage.jpg"))

这是可修复的,还是不能从 WPF / XAML 应用程序使用 ExifLib?

如果 ExifLib不是WPF / XAML 应用程序的可行解决方案,还有哪些替代方案?

更新:

使用此代码,来自 Simon McKenzie 的回答:

private void btnLoadNewPhotoset_Click(object sender, RoutedEventArgs e)
{
    using (var store = IsolatedStorageFile.GetUserStoreForApplication())
    using (var stream = store.OpenFile("testImage.jpg", FileMode.Open))
    using (var reader = new ExifReader(stream))
    {
        // ...
    }
}

我仍然收到一个错误:

命名空间“System.IO”中不存在类型或命名空间名称“IsolatedStorage”(您是否缺少程序集引用?)

这是在 Visual Studio 2013 中创建的 Windows 应用商店 (C#) 应用。该项目的属性显示它以 Windows 8.1 为目标,配置管理器显示配置 == 调试,平台 = x64)

我的项目显示的参考文献是:

.NET for Windows Store apps
Bing.Maps.Xaml
ExifLib
Microsoft Visual C++ Runtime Package
Windows 8.1

我错过了什么?

更新 2:

当我在 Assemblies.Framework 的 Reference Manager 中查看时,它说:“所有的框架组件都已被引用......”我假设 mscorlib.dll 应该是其中之一(它没有列出它们)?

我在我的硬盘上搜索“mscorlib.dll”,我有一百万个,大小和日期都不同。我应该尝试添加哪个作为参考?我的所有内容从 C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.5 日期为 2012 年 7 月 9 日,文件大小为 2,564,528 到 C:\Program Files (x86 )\Reference Assemblies\Microsoft\Framework.NETCore\v4.5.1 到...你的名字。

认为“C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETCore\v4.5.1”似乎是最好的选择,我尝试通过浏览按钮引用它,但是当我这样做时,我被责骂了:

在此处输入图像描述

为了全面披露,在 Windows 8.1 的参考管理器中,它说,“Windows 8.1. SDK 已被引用。”

对于 Windows 8.1.Extensions,它向我显示:

Microsoft Visual C++ 2013 Runtime Package for Windows 12.0 (unchecked)
Microsoft Visual C++ 2013 Runtime Package 11.0 (checked)

由于这似乎是其中一个警告的原因,我颠倒了它们的检查(检查 2013,未检查另一个)。

我还检查了:

Behaviors SDK (XAML) 12.0
SQLite for Windows Runtime 3.8.6 (because I will eventually be using SQLite in this project)

更新 3:

我刚刚发现:“隔离存储不适用于 Windows 应用商店应用程序。相反,请使用 Windows 运行时 API 中包含的 Windows.Storage 命名空间中的应用程序数据类来存储本地数据和文件。在这里

更新 4:

我正在等待西蒙的例子,但我认为它可能是这样的:

using Windows.Storage;
using ExifLib;
. . .
private async void btnOpenImgFiles_Click(object sender, RoutedEventArgs e)
{
    FileOpenPicker openPicker = new FileOpenPicker();
    openPicker.ViewMode = PickerViewMode.Thumbnail;
    openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
    openPicker.FileTypeFilter.Add(".jpg");
    openPicker.FileTypeFilter.Add(".jpeg");
    openPicker.FileTypeFilter.Add(".png");

    IReadOnlyList<StorageFile> files = await openPicker.PickMultipleFilesAsync();
    for (int i = 0; i < files.Count; i++)
    {
        using (var randomAccessStream = await files[i].OpenAsync(FileAccessMode.Read))
        using (var stream = randomAccessStream.AsStream())
        using (var exfrdr = new ExifReader(stream))
        {
            // ...exfrdr
        }
    }
}
4

2 回答 2

2

这与WPF无关
尝试这样的事情

using (ExifReader reader = new ExifReader(File.Open(@"C:\temp\testImage.jpg",FileMode.Open)))
于 2014-10-11T02:16:51.050 回答
1

字符串构造函数在 Windows Phone/Windows 应用商店应用程序中不可用,因为它们不允许直接文件系统访问。相反,您需要传入包含图像的流。这是一个使用FileOpenPicker. 请注意使用AsStream(...)将 转换IRandomAccessStream为 aStream以便与 一起使用ExifReader

using System;
using System.IO;
using Windows.Storage;
using Windows.Storage.Pickers;

// ...

var picker = new FileOpenPicker();
picker.FileTypeFilter.Add(".jpg");
var file = await picker.PickSingleFileAsync();

using (var randomAccessStream = await file.OpenAsync(FileAccessMode.Read))
{
    using (var stream = randomAccessStream.AsStream())
    {
        using (var reader = new ExifReader(stream))
        {
            string model;
            if (reader.GetTagValue(ExifTags.Model, out model))
            {
                var dialog = new MessageDialog(model, "Camera Model");
                dialog.ShowAsync();
            }
        }
    }
}
于 2014-10-11T08:44:04.790 回答