developer927
developer927

Reputation: 15

Resizing image in Xamarin Forms

I have created an app where the user can select or take a picture. This picture is then submitted to a web service, and can be a maximum size of 4MB. Some pictures are larger than this so I need to resize them before submitting to get under the 4MB limit, but doing this as little as possible to keep as much detail as possible. I couldn't find a built in way of image resizing down to a certain filesize, so to do this I have so far created a DependencyService with a specific image resizing implementation in Android and iOS.

The code that I have come up with for Android (and iOS is similar) is as follows, where I repeatedly scale the bitmap by 0.9 until it gets under the limit. Is there a better way of doing this?:

   public byte[] ResizeImage(byte[] imageData)
        {
            var originalImage = BitmapFactory.DecodeByteArray(imageData, 0, imageData.Length);
            var resizedImage = originalImage;
            double newWidth = originalImage.Width;
            double newHeight = originalImage.Height;

            while (resizedImage.ByteCount > 4194304)
            {
                newWidth *= 0.9;
                newHeight *= 0.9;
                resizedImage = Bitmap.CreateScaledBitmap(originalImage, (int) newWidth,
                    (int) newHeight, false);
            }

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

Upvotes: 1

Views: 2305

Answers (1)

Vitalii Ilchenko
Vitalii Ilchenko

Reputation: 598

I see that you use JPG without compression (in your code sample the quality is set to '100'). We also know that RGB bit depth is 24 bit/pixel. Given this we have:

ImageWidthPx * ImageHeightPx * 24/8 = TotalImageSizeInBytes

What you are looking for is:

ScaleFactor = TotalImageSizeInBytes / (ImageWidthPx * ImageHeightPx * 24/8)

And in your case:

var scaleFactor = 4194304 / (originalImage.Width * originalImage.Height * 3)

Upvotes: 1

Related Questions