2016-08-30 2 views
0

Я могу сохранить картинку в iOS и Android, но я не могу найти способ сохранить изображение в UWP. Есть идеи?Xamarin формирует UWP: как я могу сохранить jpg из ImageSource?

Заранее спасибо.

+0

Что вы пробовали до сих пор?У вас есть код? Как выглядит код iOS и Android? –

+0

Для iOS и Android он работает нормально. В UWP не работает, некоторые руководства на линии неправильны или неполны. Я могу поделиться своим кодом. – Enrico

+0

Пожалуйста, поделитесь некоторым кодом, может быть, он дает мне некоторый намек на ваши требования и то, как вы решили его в iOS и Android. Пожалуйста, обновите свой вопрос кодом и/или учебным курсом, который вы используете. –

ответ

1

Я не могу найти способ, чтобы сохранить изображение в UWP

Нет, мы не можем извлечь данные изображения из Xamarin ImageSource объекта.

Существует StreamImagesourceHandler реализация класса в UWP см 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 Runtime (W/WP8.1 & UWP), извлечение данных изображения из System.IO.Stream класс поддерживается в UWP.

Мы можем использовать 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

+0

Благодарим за помощь! – Enrico

0

Возможно, кому-то нужно решение для 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); 
     } 
    }