如何在不重新下载的情况下从ImageSource保存图像? [英] How can I save an image from an ImageSource without downloading again?

查看:120
本文介绍了如何在不重新下载的情况下从ImageSource保存图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我以前的问题的扩展

this is an extension to my previous question how should a metro app cache images for tombstoning (and should it)?

我一直在寻找的解决方案是使用HttpClient,但这会导致Web服务器上每个文件不必要的第二次点击.

The solutions that I have been finding are to use HttpClient, but this results in an unnecessary second hit per file on the web server.

反正是否有从Image/ImageSource保存现有图像/流的信息(使用ImageOpened事件以确保其可用)?

Is there anyway to save the existing image/stream from a Image/ImageSource (using the ImageOpened event to ensure it is available) ?

解决方案必须与当前的RP API配合使用,因为这是CP进行了较大更改的领域.

Solution must work with current RP API as this is an area where large changes have been made from CP.

推荐答案

首先请注意,没有做任何自定义(即,使用URI作为Image.Source),已经实现了某种缓存,就好像您在您的应用程序旁边运行Fiddler时,您会看到请求发出一次,而不是每次显示项目时发出.

First of all please note, that without doing anything custom (i.e. using a URI as an Image.Source), there's already some kind of cache implemented as if you have a Fiddler running next to your app, you'll see that requests are issued once and not each time an item is displayed.

这就是说,如果您想要某种持久性缓存,则可以创建一个Converter,该转换器检查所需图像是否在应用程序的临时目录中,如果不是,则将其下载.

This being said, if you want some kind of persistent cache, you could create a Converter which checks if the desired image is in the App's temporary directory and downloads it if it's not the case.

这是一种方法:

public sealed class UriToCachedImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        Uri uri = value as Uri;
        if (uri == null)
            return null;

        // Don't let user know those are images, yet keep a unique and consistent name.
        string fileName = Path.GetFileName(uri.AbsolutePath);
        StorageFile file = null;
        try
        {
            Task<StorageFile> task = ApplicationData.Current.TemporaryFolder.GetFileAsync(fileName).AsTask<StorageFile>();
            task.Wait();
            file = task.Result;
        }
        catch (AggregateException ex)
        {
            if (ex.InnerException is FileNotFoundException)
            {
                // http://social.msdn.microsoft.com/Forums/en-US/winappswithcsharp/thread/1eb71a80-c59c-4146-aeb6-fefd69f4b4bb/
            }
            else
            {
                throw;
            }
        }

        if (file == null)
        {
            // File isn't present in cache => download it.

            // This creates a file in the app's INetCache
            // but we can't retrieve its path or know its name for sure
            // hence we're not using this file as our cache file.
            Task<StorageFile> streamTask = StorageFile.CreateStreamedFileFromUriAsync(fileName, uri, RandomAccessStreamReference.CreateFromUri(uri)).AsTask<StorageFile>();
            streamTask.Wait();
            StorageFile storageFile = streamTask.Result;

            // Copy file to our temporary directory (can't move as we don't have write access on the initial file).
            Task<StorageFile> copyTask = storageFile.CopyAsync(ApplicationData.Current.TemporaryFolder, fileName, NameCollisionOption.ReplaceExisting).AsTask<StorageFile>();
            copyTask.Wait();
            file = copyTask.Result;
        }

        Task<IRandomAccessStreamWithContentType> openTask = file.OpenReadAsync().AsTask<IRandomAccessStreamWithContentType>();
        openTask.Wait();
        IRandomAccessStreamWithContentType randomAccessStream = openTask.Result;

        BitmapImage bitmapImage = new BitmapImage();
        bitmapImage.SetSource(randomAccessStream);
        return bitmapImage;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

注意:此代码段还说明了如何从同步方法中调用异步方法;)

Note: This code snippet also illustrates how to call async methods from a synchronous method ;)

这篇关于如何在不重新下载的情况下从ImageSource保存图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆