我在 iOS 上拍照,你知道如何减小 FilResult 的大小以转换为 base64 吗

I take a picture on iOS, do you know how to reduce the size of an FilResult to convert in base64

提问人:Antoine21000 提问时间:11/8/2023 更新时间:11/8/2023 访问量:59

问:

我在 Xamarin 中创建了一个应用程序 iOS,我尝试拍照并将其用作个人资料的图片,它工作正常,但我需要将其发送到我的数据库,而 base64 太长了。我想调整我的 FileResult 大小以减少字符数。这是我的代码:

 async Task CapturePhoto()
    {
        try
        {
            var result = await MediaPicker.CapturePhotoAsync();

            if (result != null)
            {
                Stream stream = await result.OpenReadAsync();

                using (MemoryStream memory = new MemoryStream())
                {
                    stream.CopyTo(memory);
                    byte[] bytes = memory.ToArray();
                    string base64 = Convert.ToBase64String(bytes);
                    profil.Photo = base64;
                    ImageProfil.Source = ImageSource.FromStream(() => new MemoryStream(Convert.FromBase64String(profil.Photo)));
                    Console.WriteLine(base64.Length);
                }


            }
        }
        catch (Exception e)
        {
            await DisplayAlert("Erreur", e.Message, "ok");
        }

    }

我不知道最好的选择是什么,首先调整女巫参数的大小,我已经尝试过 MagickImage,但我无法让它工作,并且在互联网上有很多解决方案,但我不确定我是否正确使用它们,如果您有想法,请告诉我。

C# Xamarin Xamarin.iOS 相机 Base64

评论

1赞 Jason 11/8/2023
github.com/xamarin/xamarin-forms-samples/tree/main/......
0赞 Antoine21000 11/8/2023
感谢您的回复,它工作正常,但它会自动旋转我的图片,我会尝试修复它。

答:

0赞 Liqun Shen-MSFT 11/8/2023 #1

减少 base64.长度,您可以调整图像大小。Jason 添加了一个很好的链接。我想添加更多详细信息并分享一个完整的解决方案。

我使用 Xamarin Forms DependencyService 制作了一个演示来调用 ios 本机代码。

1.创建界面

在共享项目中创建名为 IResizeImageInterface 的接口。并定义方法。

public interface IResizeImageInterface
{
    byte[] ResizeImage(byte[] imageData,float width,float height,float quality);
}

2.在iOS上实现界面

ResizeImageService 类是在 iOS 项目中创建的。调用此方法,我们可以根据我们传递的参数调整图像大小并降低质量。

public class ResizeImageService : IResizeImageInterface
{
    public ResizeImageService()
    {
    }

    public byte[] ResizeImage(byte[] imageData, float width,float height,float quality)
    {


        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(quality).ToArray();
        }
    }

    public static UIKit.UIImage ImageFromByteArray(byte[] data)
    {
        if (data == null)
        {
            return null;
        }

        UIKit.UIImage image;
        try
        {
            image = new UIKit.UIImage(Foundation.NSData.FromArray(data));
        }
        catch (Exception e)
        {
            Console.WriteLine("Image load failed: " + e.Message);
            return null;
        }
        return image;
    }
}

3.注册平台实现

这一步很简单。在 ResizeImageService 类中添加此行。

[assembly: Dependency(typeof(MyProjectName.iOS.ResizeImageService))]
namespace MyProjectName.iOS

现在,您可以在共享项目中调用 iOS 本机代码。

using (MemoryStream memory = new MemoryStream())
{
    //Before resize
    stream.CopyTo(memory);
    byte[] bytes = memory.ToArray();
    string base64 = Convert.ToBase64String(bytes);
    Console.WriteLine(base64.Length);

    //After resize
    IResizeImageInterface service = DependencyService.Get<IResizeImageInterface>();
    byte[] resizedImage = service.ResizeImage(bytes,400f,400f,0.2f);
    string resizedBase64 = Convert.ToBase64String(resizedImage);    
    Console.WriteLine(resizedBase64.Length);

调整图像大小后,您可能会看到长度减少。

希望对您有所帮助!

评论

0赞 Antoine21000 11/8/2023
感谢您的回答,我在这个代码中遇到了两个问题,首先,找不到“ReduceSize77439838”,第二个是 imageRect 是 RectangleF,而 DrawImage 需要 CGRect。我应该在 CGRect 中隐藏 imageRect 吗?您有“ReduceSize77439838”的解决方案吗?
0赞 Liqun Shen-MSFT 11/8/2023
哦,“ReduceSize77439838”是我的项目名称。你应该把它改成你的。而且我认为你不必皈依。我对我的答案做了一些修改。
0赞 Antoine21000 11/8/2023
谢谢它现在正在工作,但我的旋转问题与 Jason 的答案相同,我怎么能旋转它以使其在我的 base64 中处于良好位置。
0赞 Liqun Shen-MSFT 11/8/2023
哦,恐怕这是 GitHub 上的一个已知问题:MediaPicker CapturePhotoAsync - 照片旋转 90 度的方向