Xamarin.Forms 内存流操作。为什么 Android 与 iOS 不同?

Xamarin.Forms MemoryStream Manipulation. Why is Android different from iOS?

所以我正在使用 SignaturePad.PCL nuget 包,您可以从获取绘制点并创建图像的插件中恢复流。然后我将该图像作为 base 64 字符串传递给 Web 服务,并将其显示在 Web 应用程序中。好吧,我发现我能够像这样转换为 base 64 字符串

//This works on android but not iOS
string base64Str = Convert.ToBase64String(((MemoryStream) theStream).ToArray());


//Works on iOS but not android
string base64Str = Convert.ToBase64String(StreamConvert(theStream));
private byte[] StreamConvert(Stream stream){
  using (var ms = new MemoryStream())
        {
            stream.CopyTo(ms);
            return ms.ToArray();
        }​
     }


//For both I use this, unless someone else can figure out a cross platform solution
string base64Str = Convert.ToBase64String(Device.OS == TargetPlatform.Android ? ((MemoryStream) theStream).ToArray() : StreamConvert(theStream));

有人知道为什么会有差异吗?

我快速浏览了 SignaturePad 的源代码 (found here) 并回顾了 Android 和 iOS 版本如何处理它创建的图像。

主要区别在于,在 Android 上你得到一个 Bitmap 对象,而在 iOS 上你从 SignaturePad 的 GetImage() 方法中得到一个 UIImage 对象.参见 here for Android GetImage and here for iOS GetImage()

iOS

让我们先深入 UIImage (see UIImage here)。

看看 UIImage 如何生成图像,您会发现有几种方法可以 return 一个 NSData 对象:ToJPEG()ToPNG().

看看 NSData API reference,它有一个 ToStream() 方法,它 return 是一个 Stream 对象。

Android

好的,现在开始Android!

我找到了 Bitmap API docs here。您可以得到另一个 Bitmap(来自 CreateBitmap 方法)、Buffer(来自 CopyBuffer 方法)或 Compress / CompressAsync

Compress and CompressAsync 让你传入一个像 MemoryStream 这样的可写流对象作为第三个参数。这是一个例子(来自 jzeferino 的评论):

var stream = new System.IO.MemoryStream(); imageBitpmap.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);

希望这有助于阐明 SignaturePad 在为您提供图像时正在做什么。