One really hacky way to do this is to write your own renderer for your image. Then the rendering will get byte[]/Stream from the inline control. Here's a very crude implementation without error handling to help you get started:
public class MyImage : Image { public Func<byte[]> GetBytes { get; set; } }
Here's the iOS renderer:
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; } } }
Android one of them is somewhat larger:
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; } } }
And finally, the use is obvious:
var bytes = myImage.GetBytes?.Invoke();
Extending the idea of ββthreading support should be fairly simple. The obvious hurdle is that form management ( MyImage ) maintains a link to its renderer via GetBytes() , but this seems inevitable.
Nikola Irinchev
source share