【问题标题】:UWP display Image from external path?UWP显示来自外部路径的图像?
【发布时间】:2019-02-19 02:46:39
【问题描述】:

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

基本功能:

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

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

在 WPF 中,我可以将 ListBox 绑定到 InputImageObservableCollection,例如 <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,打开它并设置位图源,但我不能在属性 getter 中使用 async 方法...

有什么解决办法吗?

注意:我在 appxmanifest 中启用了 broadFileSystemAccess" 并在设置 -> 隐私 -> 文件系统中为应用打开了

【问题讨论】:

  • 您好,您可以将列表视图中的图像来源绑定到包含 uri 的字符串。无需创建 BitmapImagesource
  • @thezapper 这是我使用file:/// 样式URI 的第一种方法,但它在UWP 中不起作用,只是一个空白图像。 (我实际上正在使用 GridView 但这可能并不重要)。如果 URI 指向程序集中的某些内容(例如 Assets/...),则它可以工作,但不能在外部。
  • 愿你的图片大小是 zip。
  • @lindexi 解决了它 - 请参阅我的答案。

标签: uwp


【解决方案1】:

解决了,这是我学到的:

即使启用了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's blog 中描述的异步绑定(是的,这似乎实际上是可能的)。

程序:

安装Nito.AsyncEx NuGet 包。

对属性使用以下内容:

    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}"/>

【讨论】:

  • 但是当路径改变时,您的图像无法更新。
  • @lindexi 这对我来说不是问题,但我猜如果路径改变了,你可以从路径设置器触发 ImageAsync 的属性更改事件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多