Reputation: 15
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
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