Xamarin.Forms:将 ImageSource 转换为 Image Byte 数组

Posted

技术标签:

【中文标题】Xamarin.Forms:将 ImageSource 转换为 Image Byte 数组【英文标题】:Xamarin.Forms: convert an ImageSource an Image Byte array 【发布时间】:2021-07-10 18:37:43 【问题描述】:

我在一个 Xamarin.Forms 应用程序上工作,我在其中使用 Syncfusion SfSignaturePad 实现了签名控件

我想将签名图像发送到 API。

为此,我已将相关签名的ImageSource 转换为byte array,如下所示:

SfSignaturePad signaturePad;

public byte[] SignaturePadImage  get; set; 

private void BtnConvert_Tapped(object sender, EventArgs e)

    signaturePad.Save();
    if (signaturePad.ImageSource != null)
    
        StreamImageSource streamImageSource = (StreamImageSource)signaturePad.ImageSource;
        System.Threading.CancellationToken cancellationToken =
            System.Threading.CancellationToken.None;
        Task<Stream> task = streamImageSource.Stream(cancellationToken);
        Stream stream = task.Result;

        // store bytes
        SignaturePadImage = new byte[stream.Length];
        stream.Read(SignaturePadImage, 0, SignaturePadImage.Length);
    

这允许我将byte array 设置为SourceImage 以显示相应的图像。

但是当我将 byte array 发送到 API 时,无法识别图像格式,因为它基于 Xamarin.Forms.ImageSource

所以我想在恢复byte array之前将我的ImageSource“转换”为格式化图像(如.PNG、.BMP、...)。

实现这一目标的更好方法应该是什么?

【问题讨论】:

我建议改用 Xamarin SignaturePad 控件。 SF控制不是很灵活 这个one? 3 年后它仍然“正常工作”吗? 是的,我刚刚在一个项目中使用过,效果很好 【参考方案1】:

根据 jason 的意见,我使用 Xamarin.Controls.SignaturePad,通过signatureView.GetImageStreamAsync(SignatureImageFormat.Png) 获取图像并转换为 byte[]。

首先,安装 Xamarin.Controls.SignaturePad.Forms

然后使用 SignaturePadView,请按照以下代码。

<ContentPage
x:Class="FormsSample.images.Page1"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:SignaturePad.Forms;assembly=SignaturePad.Forms">
<ContentPage.Content>
    <StackLayout x:Name="imagestack">
       
        <Button
            x:Name="btn2"
            Clicked="btn2_Clicked"
            Text="get image from signturePadview" />
        <controls:SignaturePadView
            x:Name="signatureView"
            BackgroundColor="Gray"
            StrokeColor="White"
            StrokeWidth="3" />
    </StackLayout>
</ContentPage.Content>
private async void btn2_Clicked(object sender, EventArgs e)
    
        var image = new Xamarin.Forms.Image();
        byte[] buffer;
        using (Stream bitmap = await signatureView.GetImageStreamAsync(SignatureImageFormat.Png))
        
            if(bitmap!=null)
            
                long length = bitmap.Length;
                buffer = new byte[length];
                bitmap.Read(buffer, 0, (int)length);

                var stream1 = new MemoryStream(buffer);
                image.Source = ImageSource.FromStream(() => stream1);

                image.WidthRequest = 50;
                image.HeightRequest = 50;
                imagestack.Children.Add(image);
            
           
        
    

我将signatureView图像源转换为byte[],然后显示在Xamarin.Forms Image上,byte[]缓冲区就是你想要得到的Image Byte数组。

【讨论】:

【参考方案2】:

感谢您的建议。

最后,我实现了另一个解决方案,因为 FFImageLoading 已经在这个项目中使用。

为此,我使用CachedImage 而不是Image

<ffimageloading:CachedImage x:Name="signatureImg"
        Source="Binding Source=x:Reference SignatureView, Path=SignaturePadImageSource, Mode=TwoWay"
        IsVisible="Binding Source=x:Reference SignatureView, Path=IsSignatureMode, Converter=StaticResource InverseBoolConverter"
        VerticalOptions="FillAndExpand"
        BackgroundColor="Binding Source=x:Reference SignatureView, Path=BackColor" />

然后在我的控件的构造函数中从CachedImage订阅Success事件:

public CustomSignature()

    InitializeComponent();
    signaturePad = sfSignaturePad;
    IsSignatureMode = true;
    signatureImg.Success += SignatureImg_Success;

然后我可以使用 FFImageLoading 中的GetImageAsPngAsync() 方法。

private async void SignatureImg_Success(object sender, CachedImageEvents.SuccessEventArgs e)

    SignaturePadImage2Bytes = await signatureImg.GetImageAsPngAsync((int)signatureImg.Width, (int)signatureImg.Height);

我可以像这样共享 PNG 字节数组。

【讨论】:

以上是关于Xamarin.Forms:将 ImageSource 转换为 Image Byte 数组的主要内容,如果未能解决你的问题,请参考以下文章

将 Xamarin.Forms.Color 转换为平台特定颜色

Xamarin.Forms:Forms.Context 已过时

如何使用 DependencyService 和接口委托将 xamarin.android 特定功能的方法传递给 xamarin.forms?

Xamarin.forms 使用 php 将图像上传到服务器目录

是否可以将 Xaml 设计器或智能感知与 Xamarin.Forms 一起使用?

将 UWP 标头模板中的图标与 xamarin.forms 一起使用