0

In my application I let the users select an image (of any size). The application will then load it to an image control, resize it if needed, and display it on the screen.

I have all the saving / loading from the preferences working correctly right now as I use the Xamarin Forms Plugin.FilePicker and grab the byte array from that to save to my preferences.

The challenge I am facing is that if the uses pics a large image from their device, the large version of the image is what is uploaded to the FilePicker plugin and the byte array is too large to save. (I get the error ' The size of the state manager setting value has exceeded the limit.')

So what I would like to do is take the contents of the image control, which have been resized to a manageable size, convert that to a byte array and then save that in my preferences.

Any idea how I can convert the content of the image control into a byte array so I can serialize it in JSON and save it to my preferences?? Below is that code that saves the Byte Array from the file picker.

private async void btnChooseFile_Clicked(object sender, System.EventArgs e)
{
    try
    {
        FileData fileData = await CrossFilePicker.Current.PickFile();
        if (fileData == null)
            return; // user canceled file picking

        //lblFilePath.Text = fileData.FileName;

        imgIcon.Source = ImageSource.FromStream(() => fileData.GetStream());

        // THIS IS THE LINE OF CODE I NEED TO CHANGE TO IT SAVES THE 
        // BYTE ARRAY OF THE SMALLER IMAGE AS DISPLAYED BY THE 
        // IMAGE CONTROL INSTEAD OF THE FULL SIZE FILE THE USER
        // SELECTED 
        ViewModelObjects.AppSettings.KioskIcon = fileData.DataArray;

    }
    catch (Exception ex)
    {
        System.Console.WriteLine("Exception choosing file: " + ex.ToString());
    }

}
4
  • AFAIK you can't do this. The image control doesn't expose the internal representation of the image. You will need to resize the image yourself before uploading. Commented Aug 15, 2019 at 17:50
  • I am not in control of the image, the users are. Is there a way I can programmatically resize it before assigning the value to the image control? Commented Aug 15, 2019 at 17:52
  • Sure, use SkiaSharp or do it in platform code, or find a plugin that will do it for you Commented Aug 15, 2019 at 17:55
  • So actually, rather than resizing the image, I am just going to check if it is too large to store in the preferences. If it is I will give the user an alert and make them resize or pick a different image. Commented Aug 16, 2019 at 22:49

1 Answer 1

1

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

 #if __IOS__
    public static byte[] ResizeImageIOS(byte[] imageData, float width, float height)
    {
        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().ToArray();
        }
    }


#if __ANDROID__

    public static byte[] ResizeImageAndroid (byte[] imageData, float width, float height)
    {
        // Load the bitmap
        Bitmap originalImage = BitmapFactory.DecodeByteArray (imageData, 0, imageData.Length);
        Bitmap resizedImage = Bitmap.CreateScaledBitmap(originalImage, (int)width, (int)height, false);

        using (MemoryStream ms = new MemoryStream())
        {
            resizedImage.Compress (Bitmap.CompressFormat.Jpeg, 100, ms);
            return ms.ToArray ();
        }
    }

you could refer to ImageResizer

Sign up to request clarification or add additional context in comments.

3 Comments

So this is cross platform, not just iOS. In actuality, the app I am working on is for UWP and MacOS.
@GeorgeMCeaserJr you could open the link,it also have the method for UWP
I understand but it is separate code by platform that has to be maintained. For me, I would prefer a single code source. :) I may have to do some other stuff with images later and if I do I will come back to your samples. Thank you for providing them.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.