我一直在深入研究 Xamarin.Forms.Labs,以了解有关如何访问和操作图像的更多信息。将图像保存到 Android/iOS 照片库效果很好,从其中检索图像也是如此,至少在用户交互时是这样。
问题是我希望能够在程序内部保存一些文件。实际上保存文件本身似乎不是问题 - 我已经为此编写了一个接口(interface)/DependencyService 解决方案。
我似乎无法使用 Xamarin.Forms Image 或 ImageSource 访问 bytes[] 或图像数据本身的流。使用静态方法将流读入 ImageSource 相对简单,那么我如何取出这些字节以便将文件保存在程序本身中?
框架:我现在正在开发一个应用程序,用户可以在该应用程序中拍摄/选择要包含在表单中的图片,并且该表单最终会发布到网站上。因此,能够实际保存图片或访问数据本身以进行传输非常关键。
最佳答案
一个非常 hacky 的方法是为您的图像编写一个自定义渲染器。然后渲染器将从 native 控件获取 byte[]/Stream
。这是一个非常粗略的实现,没有任何错误处理来帮助您入门:
public class MyImage : Image
{
public Func<byte[]> GetBytes { get; set; }
}
这是 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;
}
}
}
Android 有点复杂:
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;
}
}
}
最后,用法是显而易见的:
var bytes = myImage.GetBytes?.Invoke();
扩展想法以支持流应该非常简单。明显的警告是表单控件 (MyImage
) 通过 GetBytes()
保留对其渲染器的引用,但这似乎是不可避免的。
关于c# - 在 Xamarin.Forms 中获取 Image 或 ImageSource 的 bytes[]/stream?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25938386/