如何调整 xamarin.forms 中的图像大小?

Posted

技术标签:

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

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

【问题讨论】:

看到这个帖子:forums.xamarin.com/discussion/37681/… 虽然你需要从德语翻译一点:) 嗨,Jason,使用了 Bitmap,但是我如何在 xamarin.forms 中使用 Bitmap。我需要为 xamarin.forms 中的位图使用什么参考? 阅读弗雷迪在帖子中的笔记。他将其编写为一个共享项目——位图参考位于代码的 android 部分,而不是 ios。如果您不想使用共享项目,则需要重构以使用特定于平台的项目和 DI。 【参考方案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));

以上是关于如何调整 xamarin.forms 中的图像大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何Xamarin.Forms调整水平的ListView的大小

Xamarin.Forms android - 调整控件大小以考虑可访问性设置

如何在 Xamarin 中调整按钮的大小

Xamarin.Forms ListView 大小到内容?

如何在 iOS 的 xamarin.forms 应用程序中设置应用程序的应用程序图标

在 Xamarin Forms 自定义标签渲染器中,增加边界的大小