Xamarin形成UWP:如何从ImageSource保存jpg?

时间:2016-08-30 15:40:11

标签: xamarin.forms uwp

我可以在iOS和Android中保存图片,但我找不到在UWP中保存图像的方法。有什么想法吗?

提前谢谢。

2 个答案:

答案 0 :(得分:1)

也许某人需要iOS和Android的解决方案(下图)。与此同时,我正在等待UWP的想法。

的iOS

     /// <summary>
    /// Saves the picture to disk.
    /// </summary>
    /// <returns>The picture to disk.</returns>
    /// <param name="imgSrc">Image source.</param>
    /// <param name="id">Identifier.</param>
    /// <param name="overwriteIfExist">if set to <c>true</c> overwrite if exist.</param>
    /// <returns>The picture to disk.</returns>
    public async void SaveImage(ImageSource imgSrc, string id, bool overwriteIfExist = false)
    {
        var renderer = new StreamImagesourceHandler();
        var photo = await renderer.LoadImageAsync(imgSrc);

        string jpgFilename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), id + ".jpg");

        if (File.Exists(jpgFilename))
        {
            File.Delete(jpgFilename);
        }

        NSData imgData = photo.AsJPEG();
        NSError err;
        if (imgData.Save(jpgFilename, false, out err))
        {
            Console.WriteLine("saved as " + jpgFilename);
        }
        else
        {
            Console.WriteLine("NOT saved as " + jpgFilename
                                + " because" + err.LocalizedDescription);
        }

    }

很高兴知道,当iOS将图像保存为 jpg 时,图像标题会显示 png

的Android

    /// <summary>
    /// Saves the picture to disk.
    /// </summary>
    /// <param name="imgSrc">Image source.</param>
    /// <param name="id">The image identifier.</param>
    /// <param name="overwriteIfExist">if set to <c>true</c> overwrite if exist.</param>
    /// <returns>The picture to disk.</returns>
    public async void SaveImage(ImageSource imgSrc, string id,
                                        bool overwriteIfExist = false)
    {
        var renderer = new StreamImagesourceHandler();
        var photo = await renderer.LoadImageAsync(imgSrc, Forms.Context);

        string jpgFilename = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), id + ".jpg");

        if (File.Exists(jpgFilename))
        {
            File.Delete(jpgFilename);
        }

        using (FileStream fs = new FileStream(jpgFilename, FileMode.OpenOrCreate))
        {
            photo.Compress(Bitmap.CompressFormat.Jpeg, 100, fs);
        }
     }

答案 1 :(得分:1)

  

我找不到在UWP中保存图像的方法

不,我们无法从Xamarin ImageSource对象中提取图像数据。

UWP中有StreamImagesourceHandler个类实现,请参阅here

public sealed class StreamImageSourceHandler : IImageSourceHandler
{
    public async Task<Windows.UI.Xaml.Media.ImageSource> LoadImageAsync(ImageSource imagesource, CancellationToken cancellationToken = new CancellationToken())
    {
        BitmapImage bitmapimage = null;

        //Omitted

        return bitmapimage;
    }
}

因此我们需要从BitmapImage中提取数据。

实际上BitmapImage类是继承自ImageSource类,而我们无法从ImageSource中提取图像数据,因此请看这两个问题:

此处的解决方案是对Windows运行时(W / WP8.1和UWP)应用程序使用不同的方法,在UWP中支持从System.IO.Stream类提取图像数据。

我们可以使用DependencyService来访问本机平台功能,首先,在PCL中创建一个界面:

public interface ISaveImage
{
    void SavePictureToDisk(ImageSource imgSrc, string Id, bool OverwriteIfExist = false);
    void SavePictureToDiskWINRT(System.IO.Stream imgStream, string Id, bool OverwriteIfExist = false);
}

在Xamarin页面背后的代码中:

    var memoryStream = new MemoryStream(Convert.FromBase64String("iVBOxxxxxxxxxxMVEX/uQOAuwPzUxxxxxxxxxxxx="));
    ImageSource imgsource = ImageSource.FromStream(() => memoryStream);

    if (Device.OS == TargetPlatform.Windows|| Device.OS == TargetPlatform.WinPhone)
         DependencyService.Get<ISaveImage>().SavePictureToDiskWINRT(memoryStream, "1");
    else
         DependencyService.Get<ISaveImage>().SavePictureToDisk(imgsource, "1");

在UWP平台中实现界面:

using Xamarin.Forms;
using WorkingWithImages.WinUniversal;
using System.IO;
using System;
using Windows.Storage.Streams;

[assembly: Xamarin.Forms.Dependency(typeof(SaveImageImplementation))]
namespace WorkingWithImages.WinUniversal
{
    public class SaveImageImplementation : ISaveImage
    {
        public SaveImageImplementation() { }

        public void SavePictureToDisk(ImageSource imgSrc, string Id, bool OverwriteIfExist = false)
        {
            throw new NotImplementedException();
        }

        public async void SavePictureToDiskWINRT(Stream imgStream, string Id, bool OverwriteIfExist = false)
        {
            var inStream = imgStream.AsRandomAccessStream();
            var fileBytes = new byte[inStream.Size];
            using (DataReader reader = new DataReader(inStream))
            {
                await reader.LoadAsync((uint)inStream.Size);
                reader.ReadBytes(fileBytes);
            }

            var file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(Id+".jpg", Windows.Storage.CreationCollisionOption.ReplaceExisting);
            using (var fs = await file.OpenAsync(Windows.Storage.FileAccessMode.ReadWrite))
            {
                var outStream = fs.GetOutputStreamAt(0);
                var dataWriter = new DataWriter(outStream);
                dataWriter.WriteBytes(fileBytes);
                await dataWriter.StoreAsync();
                dataWriter.DetachStream();
                await outStream.FlushAsync();
                outStream.Dispose();
                fs.Dispose();
            }
        }
    }
}

请在here

中查看已完成的演示

关于UWP文件存储指南,请参阅Create, write, and read a file