0
votes

I want my users to upload their own custom image for the banner of my Xamarin Forms application. My thought was to have them upload the highest resolution / size image (xxxhdpi size from Android) and then scale it down in order to (hopefully) retain the quality of the image. Is there a way for me to find how much I should scale the image based on the device's screen? It does not have to be perfect. I would be happy with simply being able to determine what size image the app is selecting for the app images (i.e. @2x, xxhdpi etc.). For example, on iOS, if the app was using the @3x images, I would scale my image size down by 25%. This is making the assumption that the size of the image uploaded is for the xxxhdpi size for Android. If the app were running on an xxxhdpi screen in Android, no scaling would be done. Any idea how to do this?

UPDATE!! OK so I can use the DeviceDisplay.MainDisplayInfo.Density to determine what type of screen I am running on. My challenge now is how to resize my image control. Here is my basic thought:

I am going to have all users upload an image that is 400 units tall (the width can pretty much be what they want.) I will use the density to calculate how much I want to down scale the image using a percent i.e. XXX on Android would be 100% xx on Android and @3 on iOS would be 75%, X on Android and @2 on iOS would be 50% and the base images for iOS (@1) and Android (base srawable folder size) will be 25%. The challenge now is where can I perform this scaling on the image control? I actually have the image control in a ContentView that I share across several applications so there is no OnAppearing to override. Is there an event on the image control that I could hook into in order to resize the control. It could also be an event for the ContentView. I have tried calling a custom method in the ContentView but when I call it the height and Width of the image control as 1. I am also open to doing the resizing in memory (the image is stored in a byte array) but I want the solution to be cross platform (iOS, Androind, Windows and MacOS) Any ideas how to do this would be appreciated.

2
the Image control will scale the image for you. What's the purpose of manually scaling the image?Jason
You just need to crop the image in aspect ratio and image control will scale the image. Say, if you banner size is 500x200 then whenever user selects image to upload, just let them crop the image they selected in that ratio!Nirmal Subedi
OK so there is no need to do anything in the app. The image control will take care of everything? If so that is GREAT! :)George M Ceaser Jr
Image control comes with properties to fill the image view with or without aspect ratio. But again, to maintain the display of users image inside your fixed size image view you might want to crop the image and store it.Nirmal Subedi
OK I have tried this and it does not appear to work. The image control is simply displaying the image at the size I uploaded it as. I am always going to upload a 600 X 300 image and I want scale it down accordingly. To be clear I am not setting a size for the image control and the Image file is being selected from the local hard drive and uploaded into the application.George M Ceaser Jr

2 Answers

2
votes

you could get the Density of your device by DeviceDisplay in Xamarin.Forms via Xamarin.Essentials like :

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

then you could base on the dpi to determine what size your device is (could refer to 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). 

then you could resize the image size befor assigning the value to the image control

refer to ImageResizer

0
votes

OK so here is what I ended up doing. I ask my users to upload their biggest sized image into the app (for me that is an image with a height of 400 and a width that will fit on the screen they plan to use.)

Then I used the Xamarin.Essentials code above to get the display density for the device screen. I also created a Boolean instance variable to know if the image had already been resized. Then I added the following code into the SizeChanged event of the image and placed the following code in there:

   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);
        }
    }

This seems to have done the trick for what I was trying to accomplish.