【问题标题】:xamarin forms get byte array from image controlxamarin 表单从图像控件获取字节数组
【发布时间】:2019-12-22 03:32:12
【问题描述】:

在我的应用程序中,我让用户选择一个图像(任意大小)。然后,应用程序会将其加载到图像控件中,根据需要调整其大小,并将其显示在屏幕上。

当我使用 Xamarin Forms Plugin.FilePicker 并从中获取字节数组以保存到我的首选项时,我的首选项中的所有保存/加载现在都可以正常工作。

我面临的挑战是,如果用户使用他们设备中的大图像,则图像的大版本是上传到 FilePicker 插件的内容,并且字节数组太大而无法保存。 (我收到错误“状态管理器设置值的大小已超出限制。”)

所以我想做的是获取图像控件的内容,这些内容已调整为可管理的大小,将其转换为字节数组,然后将其保存在我的首选项中。

知道如何将图像控件的内容转换为字节数组,以便我可以将其序列化为 JSON 并将其保存到我的偏好中吗?下面是从文件选择器中保存字节数组的代码。

private async void btnChooseFile_Clicked(object sender, System.EventArgs e)
{
    try
    {
        FileData fileData = await CrossFilePicker.Current.PickFile();
        if (fileData == null)
            return; // user canceled file picking

        //lblFilePath.Text = fileData.FileName;

        imgIcon.Source = ImageSource.FromStream(() => fileData.GetStream());

        // THIS IS THE LINE OF CODE I NEED TO CHANGE TO IT SAVES THE 
        // BYTE ARRAY OF THE SMALLER IMAGE AS DISPLAYED BY THE 
        // IMAGE CONTROL INSTEAD OF THE FULL SIZE FILE THE USER
        // SELECTED 
        ViewModelObjects.AppSettings.KioskIcon = fileData.DataArray;

    }
    catch (Exception ex)
    {
        System.Console.WriteLine("Exception choosing file: " + ex.ToString());
    }

}

【问题讨论】:

  • AFAIK 你不能这样做。图像控件不公开图像的内部表示。您需要在上传之前自行调整图片大小。
  • 我无法控制图像,用户可以。有没有办法在将值分配给图像控件之前以编程方式调整它的大小?
  • 当然,使用 SkiaSharp 或在平台代码中执行,或找到一个插件为您执行此操作
  • 所以实际上,我并没有调整图像的大小,而是检查它是否太大而无法存储在首选项中。如果是,我会给用户一个提醒,让他们调整大小或选择不同的图像。

标签: arrays image xamarin.forms user-preferences


【解决方案1】:

您可以在将值分配给图像控件之前调整图像大小:

 #if __IOS__
    public static byte[] ResizeImageIOS(byte[] imageData, float width, float height)
    {
        UIImage originalImage = ImageFromByteArray(imageData);
        UIImageOrientation orientation = originalImage.Orientation;

        //create a 24bit RGB image
        using (CGBitmapContext context = new CGBitmapContext(IntPtr.Zero,
                                             (int)width, (int)height, 8,
                                             4 * (int)width, CGColorSpace.CreateDeviceRGB(),
                                             CGImageAlphaInfo.PremultipliedFirst))
        {

            RectangleF imageRect = new RectangleF(0, 0, width, height);

            // draw the image
            context.DrawImage(imageRect, originalImage.CGImage);

            UIKit.UIImage resizedImage = UIKit.UIImage.FromImage(context.ToImage(), 0, orientation);

            // save the image as a jpeg
            return resizedImage.AsJPEG().ToArray();
        }
    }


#if __ANDROID__

    public static byte[] ResizeImageAndroid (byte[] imageData, float width, float height)
    {
        // Load the bitmap
        Bitmap originalImage = BitmapFactory.DecodeByteArray (imageData, 0, imageData.Length);
        Bitmap resizedImage = Bitmap.CreateScaledBitmap(originalImage, (int)width, (int)height, false);

        using (MemoryStream ms = new MemoryStream())
        {
            resizedImage.Compress (Bitmap.CompressFormat.Jpeg, 100, ms);
            return ms.ToArray ();
        }
    }

您可以参考ImageResizer

【讨论】:

  • 所以这是跨平台的,而不仅仅是 iOS。实际上,我正在开发的应用程序适用于 UWP 和 MacOS。
  • @GeorgeMCeaserJr 你可以打开链接,它也有UWP的方法
  • 我明白,但它是必须维护的平台的单独代码。对我来说,我更喜欢单一的代码源。 :) 稍后我可能需要对图像做一些其他的事情,如果我这样做了,我会回到你的样本。感谢您提供它们。
猜你喜欢
  • 2022-10-06
  • 2016-09-20
  • 1970-01-01
  • 2017-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-13
  • 2017-10-09
相关资源
最近更新 更多