如何在 Xamarin Forms 中使用上传的图片

How to use an uploaded image in Xamarin Forms

我希望我的用户为我的 Xamarin Forms 应用程序的横幅上传他们自己的自定义图像。我的想法是让他们上传最高分辨率/尺寸的图像(来自 Android 的 xxxhdpi 尺寸),然后将其缩小以(希望)保持图像质量。有没有办法让我找到我应该根据设备屏幕缩放图像的程度?它不必是完美的。如果能够简单地确定应用程序为应用程序图像选择的图像尺寸(即@2x、xxhdpi 等),我会很高兴。例如,在 iOS 上,如果应用程序使用 @3x 图片,我会将图片尺寸缩小 25%。这是假设上传的图像的大小是 Android 的 xxxhdpi 大小。如果应用 运行 在 Android 的 xxxhdpi 屏幕上,则不会进行任何缩放。知道怎么做吗?

更新!! 好的,所以我可以使用 DeviceDisplay.MainDisplayInfo.Density 来确定我 运行 所在的屏幕类型。我现在的挑战是如何调整图像控件的大小。这是我的基本想法:

我要让所有用户上传一张 400 单位高的图片(宽度几乎可以是他们想要的。)我将使用密度来计算我想使用百分比,即 Android 上的 XXX 在 Android 上为 100% xx,在 iOS 上为 @3 为 75%,在 Android 上为 X,在 iOS 上为 @2将为 50%,iOS (@1) 和 Android(基本可绘制文件夹大小)的基本图像将为 25%。现在的挑战是我在哪里可以对图像控件执行缩放?我实际上在一个 ContentView 中有图像控件,我在多个应用程序之间共享它,因此没有 OnAppearing 可以覆盖。图像控件上是否有我可以挂钩以调整控件大小的事件。它也可以是 ContentView 的事件。我试过在 ContentView 中调用自定义方法,但是当我调用它时,图像控件的高度和宽度为 1。我也愿意在内存中调整大小(图像存储在字节数组中),但我想要跨平台解决方案(iOS、Android、Windows 和 MacOS)任何想法如何做到这一点将不胜感激。

您可以通过 DeviceDisplay 在 Xamarin.Forms 中通过 Xamarin.Essentials 获取设备的 Density,例如:

var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
// Screen density
var density = mainDisplayInfo.Density;
//for Android
var dpi = density * 160; 

那么你可以根据dpi来判断你的设备尺寸是多少(可以参考densities

mdpi    Resources for medium-density (mdpi) screens (~160dpi). (This is the baseline density.)
hdpi    Resources for high-density (hdpi) screens (~240dpi).
xhdpi   Resources for extra-high-density (xhdpi) screens (~320dpi).
xxhdpi  Resources for extra-extra-high-density (xxhdpi) screens (~480dpi).
xxxhdpi Resources for extra-extra-extra-high-density (xxxhdpi) uses (~640dpi). 

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

参考ImageResizer

好的,这就是我最后做的事情。我要求我的用户将他们最大尺寸的图片上传到应用程序中(对我来说,这是一张高度为 400 且宽度适合他们计划使用的屏幕的图片。)

然后我使用上面的 Xamarin.Essentials 代码来获取设备屏幕的显示密度。我还创建了一个布尔实例变量来了解图像是否已经调整过大小。然后我将以下代码添加到图像的 SizeChanged 事件中,并将以下代码放在那里:

   private void imgBanner_SizeChanged(object sender, EventArgs e)
    {
        double ld_ScaleFactor = 0;
        try
        {
            if (imgBanner.Height <= 1)
            {
                ib_ImageResized = false;
            }
            else if (ib_ImageResized == false)
            {
                ib_ImageResized = true;

                if (id_ScreenScale < 2)
                {
                    ld_ScaleFactor = .25;
                }
                else if (id_ScreenScale < 3)
                {
                    ld_ScaleFactor = .5;
                }
                else if (id_ScreenScale < 4)
                {
                    ld_ScaleFactor = .75;
                }
                else
                {
                    ld_ScaleFactor = 1;
                }

                if  (ld_ScaleFactor < 1)
                {
                    ld_ScaleFactor += .25;
                }

                imgBanner.HeightRequest = imgBanner.Height * ld_ScaleFactor;
                imgBanner.WidthRequest = imgBanner.Width * ld_ScaleFactor;
            }
        }
        catch (Exception ex)
        {
            ErrorHandler.ProcessException(ex);
        }
    }

这似乎已经达到了我想要完成的目的。