【问题标题】:How to resize images in xamarin.forms?如何调整 xamarin.forms 中的图像大小?
【发布时间】:2021-08-20 20:50:18
【问题描述】:

我正在研究 xamarin.forms。我必须从图库中选择图像,然后调整它们的大小,然后将它们上传到服务器上。但我不知道如何以给定的特定尺寸调整所选图像的大小? 请告诉我我该怎么做?

【问题讨论】:

  • 虽然你需要从德语翻译一点:)
  • 嗨,Jason,使用了 Bitmap,但是我如何在 xamarin.forms 中使用 Bitmap。我需要为 xamarin.forms 中的位图使用什么参考?
  • 阅读弗雷迪在帖子中的笔记。他将其编写为一个共享项目——位图参考位于代码的 Android 部分,而不是 iOS。如果您不想使用共享项目,则需要重构以使用特定于平台的项目和 DI。

标签: xamarin.forms


【解决方案1】:

这可以与流(如果您使用媒体插件https://github.com/jamesmontemagno/MediaPlugin)或标准字节数组一起使用。

// If you already have the byte[]
byte[] resizedImage = await CrossImageResizer.Current.ResizeImageWithAspectRatioAsync(originalImageBytes, 500, 1000);

// If you have a stream, such as:
// var file = await CrossMedia.Current.PickPhotoAsync(options);
// var originalImageStream = file.GetStream();
byte[] resizedImage = await CrossImageResizer.Current.ResizeImageWithAspectRatioAsync(originalImageStream, 500, 1000);

【讨论】:

  • 不确定是否过时,但CrossImageResizer 不是您提到的库的一部分
【解决方案2】:

我尝试使用CrossImageResizer.Current...,但在Media Plugin 中没有找到它。相反,我发现了一个名为 MaxWidthHeight 的选项,它仅在您还添加 PhotoSize = PhotoSize.MaxWidthHeight 选项时才有效。

例如

 var file = await CrossMedia.Current.PickPhotoAsync(new PickMediaOptions() { PhotoSize = PhotoSize.MaxWidthHeight, MaxWidthHeight = 600 });
 var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions { PhotoSize = PhotoSize.MaxWidthHeight, MaxWidthHeight = 600 });

【讨论】:

    【解决方案3】:

    可悲的是,没有一个好的跨平台图像调整器(我在发这篇文章时发现的)。图像处理并非真正设计为在 iOS 和 Android 的跨平台环境中进行。使用特定于平台的代码在每个平台上执行此操作会更快、更清晰。您可以使用依赖注入和 DependencyService(或任何其他服务或 IOC)来做到这一点。

    AdamP 对如何做到这一点给出了很好的回应Platform Specific Image Resizing

    【讨论】:

    • 您能在此处添加代码吗?因为链接/页面会随着时间的推移而消失..
    【解决方案4】:

    这是从上面链接中获取的代码。

    iOS

    public class MediaService : IMediaService
    {
    
        public byte[] ResizeImage(byte[] imageData, float width, float height)
        {
    
            UIImage originalImage = ImageFromByteArray(imageData);
    
            var originalHeight = originalImage.Size.Height;
            var originalWidth = originalImage.Size.Width;
    
            nfloat newHeight = 0;
            nfloat newWidth = 0;
    
            if (originalHeight > originalWidth)
            {
                newHeight = height;
                nfloat ratio = originalHeight / height;
                newWidth = originalWidth / ratio;
            }
            else 
            {
                newWidth = width;
                nfloat ratio = originalWidth / width;
                newHeight = originalHeight / ratio;
            }
    
            width = (float)newWidth;
            height = (float)newHeight;
    
            UIGraphics.BeginImageContext(new SizeF(width, height));
            originalImage.Draw(new RectangleF(0, 0, width, height));
            var resizedImage = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();
    
            var bytesImagen = resizedImage.AsJPEG().ToArray();
            resizedImage.Dispose();
            return bytesImagen;
       }          
    }
    

    安卓

    public class MediaService : IMediaService
    {
    
        public byte[] ResizeImage(byte[] imageData, float width, float height)
        {
            // Load the bitmap 
            BitmapFactory.Options options = new BitmapFactory.Options();// Create object of bitmapfactory's option method for further option use
            options.InPurgeable = true; // inPurgeable is used to free up memory while required
            Bitmap originalImage = BitmapFactory.DecodeByteArray(imageData, 0, imageData.Length, options);
    
            float newHeight = 0;
            float newWidth = 0;
    
            var originalHeight = originalImage.Height;
            var originalWidth = originalImage.Width;
    
            if (originalHeight > originalWidth)
            {
                newHeight = height;
                float ratio = originalHeight / height;
                newWidth = originalWidth / ratio;
            }
            else 
            {
                newWidth = width;
                float ratio = originalWidth / width;
                newHeight = originalHeight / ratio;
            }
    
            Bitmap resizedImage = Bitmap.CreateScaledBitmap(originalImage, (int)newWidth, (int)newHeight, true);
    
            originalImage.Recycle();
    
            using (MemoryStream ms = new MemoryStream())
            {
                resizedImage.Compress(Bitmap.CompressFormat.Png, 100, ms);
    
                resizedImage.Recycle();
    
                return ms.ToArray();
            }
        }
    

    WinPhone

    public class MediaService : IMediaService
    {
        private MediaImplementation mi = new MediaImplementation();
    
        public byte[] ResizeImage(byte[] imageData, float width, float height)
        {
            byte[] resizedData;
    
            using (MemoryStream streamIn = new MemoryStream(imageData))
            {
                WriteableBitmap bitmap = PictureDecoder.DecodeJpeg(streamIn, (int)width, (int)height);
    
                float Height = 0;
                float Width = 0;
    
                float originalHeight = bitmap.PixelHeight;
                float originalWidth = bitmap.PixelWidth;
    
                if (originalHeight > originalWidth)
                {
                    Height = height;
                    float ratio = originalHeight / height;
                    Width = originalWidth / ratio;
                }
                else
                {
                    Width = width;
                    float ratio = originalWidth / width;
                    Height = originalHeight / ratio;
                }
    
                using (MemoryStream streamOut = new MemoryStream())
                {
                    bitmap.SaveJpeg(streamOut, (int)Width, (int)Height, 0, 100);
                    resizedData = streamOut.ToArray();
                }
            }
            return resizedData;
        }
    }
    

    编辑:如果您已经在项目中使用 FFImageLoading,那么您可以将其用于您的平台。

    https://github.com/luberda-molinet/FFImageLoading

    【讨论】:

    • 嗨henda,iOS示例缺少此方法ImageFromByteArray(imageData);。
    • 嗨,Matas,最后我从未使用过这些方法,我只是为 Android 开发,所以从未测试过 iOS 实现。我最终使用了来自github.com/luberda-molinet/FFImageLoading 的 FFImageLoading,因为它具有调整大小的方法,输出质量不错。
    • 试试 UIImage originalImage = UIImage.LoadFromData(NSData.FromArray(imageData));
    猜你喜欢
    • 2021-06-20
    • 1970-01-01
    • 2016-08-14
    • 2020-10-02
    相关资源
    最近更新 更多