Obteniendo los bytes / stream de una image o ImageSource en Xamarin.Forms?

He estado investigando en Xamarin.Forms.Labs para get más información sobre cómo se accede y manipula las imágenes. Guardar una image en una galería de fotos de Android / iOS funciona bien, al igual que recuperar una image de cualquiera, al less con la interacción del usuario.

El problema es que me gustaría poder save algunos files internamente en el progtwig. En realidad, save un file en sí no parece ser un problema; he escrito una interfaz / solución de DependencyService para eso.

Lo que no puedo hacer es acceder a los bytes [] o la transmisión de los datos de la image con una image Xamarin.Forms o ImageSource. Leer una secuencia en ImageSource es relativamente sencillo con el método estático, entonces, ¿cómo obtengo estos bytes para save el file dentro del progtwig?

Para enmarcar esto: estoy trabajando en una aplicación en este momento donde el usuario toma / selecciona imágenes para include dentro de un formulario, y el formulario finalmente se publica en un website. Así que poder save las imágenes, o acceder a los datos para transferirlos, es una buena key.

Una manera realmente hacker de hacerlo sería escribir un renderizador personalizado para tu image. Entonces, el procesador obtendrá el byte[]/Stream del control nativo. Aquí hay una implementación muy aproximada sin ningún tipo de event handling errores para ayudarlo a comenzar:

 public class MyImage : Image { public Func<byte[]> GetBytes { get; set; } } 

Aquí está el renderizador de iOS :

 public class MyImageRenderer : ImageRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Image> e) { base.OnElementChanged(e); var newImage = e.NewElement as MyImage; if (newImage != null) { newImage.GetBytes = () => { return this.Control.Image.AsPNG().ToArray(); }; } var oldImage = e.OldElement as MyImage; if (oldImage != null) { oldImage.GetBytes = null; } } } 

El de Android está un poco más involucrado:

 public class MyImageRenderer : ImageRenderer { protected override void OnElementChanged(ElementChangedEventArgs<Image> e) { base.OnElementChanged(e); var newImage = e.NewElement as MyImage; if (newImage != null) { newImage.GetBytes = () => { var drawable = this.Control.Drawable; var bitmap = Bitmap.CreateBitmap(drawable.IntrinsicWidth, drawable.IntrinsicHeight, Bitmap.Config.Argb8888); drawable.Draw(new Canvas(bitmap)); using (var ms = new MemoryStream()) { bitmap.Compress(Bitmap.CompressFormat.Png, 100, ms); return ms.ToArray(); } }; } var oldImage = e.OldElement as MyImage; if (oldImage != null) { oldImage.GetBytes = null; } } } 

Y, por último, el uso es el tipo de obvio:

 var bytes = myImage.GetBytes?.Invoke(); 

Extender la idea para soportar transmisiones debería ser bastante sencillo. La advertencia obvia es que el control de formularios ( MyImage ) conserva una reference a su renderizador a través de GetBytes() , pero parece ser inevitable.