0

我正在尝试将一个简单的 WPF 程序移植到 UWP。它是一种将一些自定义图像分析例程应用于一堆图像的工具。

基本功能:

  1. 将图像添加到图库视图(可能是 100,000 张图像)
  2. 对图像进行分析
  3. 导出数据

我遇到的问题是在画廊中显示图像。

在 WPF 中,我可以ListBox绑定到类似ObservableCollectionInputImage<Image Source={Binding Image, IsAsync=True} />

public class InputImage
{
    public string Path { get; set; }

    public BitmapImage Source
    {
        get
        {
            var image = new BitmapImage(new Uri(Path, UriKind.Absolute));
            image.Freeze();
            return image;
        }
    }
}

UWP 中的等价物是什么?

  • 我已经尝试了上述方法(减去IsAsyncFreeze部分),但图像的宽度和高度为 0。
  • 我想也许我必须StorageFile从路径创建一个,打开它并设置位图源,但我不能使用async属性 getter 中的方法......

有什么解决办法吗?

注意:我在 appxmanifest 中启用了 broadFileSystemAccess" 并在 Settings -> Privacy -> File System 中为应用打开了

4

1 回答 1

3

解决了,这是我学到的:

即使broadFileSystemAccess启用,外部文件似乎也必须通过StorageFile. 例如

StorageFile file = await StorageFile.GetFileFromPathAsync(@"C:\path\to\file");

BitmapImage您可以在首次加载图像列表时实例化该属性并直接绑定到该属性,例如

BitmapImage image = new BitmapImage();
var storageFile = await StorageFile.GetFileFromPathAsync(path);
using (IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read))
{
    await image.SetSourceAsync(stream);
}
InputImage.Source = image;

这对于单个图像来说很好,但是对于 1000 个图像存在一个问题 - 每个图像都被加载,占用大量时间和内存,即使使用 GridView 和其他控件的虚拟化方面也是如此。

解决方案是使用异步绑定(是的,这似乎实际上是可能的),如Stephen Cleary 的博客中所述。

程序:

安装Nito.AsyncExNuGet 包。

使用以下属性:

    public INotifyTaskCompletion<BitmapImage> ImageAsync
    {
        get { return NotifyTaskCompletion.Create(GetImageAsync()); }
    }

    public async Task<BitmapImage> GetImageAsync()
    {
        BitmapImage image = new BitmapImage();
        var storageFile = await StorageFile.GetFileFromPathAsync(Path);
        using (IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read))
        {
            await image.SetSourceAsync(stream);
        }
        return image;
    }

然后绑定图像作为此任务的结果,注意使用Binding而不是x:Bind

<Image Source="{Binding ImageAsync.Result}"/>
于 2019-02-20T12:10:22.943 回答