What I've found is probably not a really good approach, but that at least worked for me:
YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null); //create YuvImage instance with initial size
ByteArrayOutputStream bao = new ByteArrayOutputStream();
image.compressToJpeg(new Rect(0, 0, image.getWidth(), image.getHeight()), jpegQuality, bao);
I have aspect
value which is set outside. This value represents multiplier, how much do we decrease the scale, i.g. if aspect == 1
, we use same resolution. If aspect == 2
we divide image resolution by 2 and etc. Scaling required only in case if aspect != 1
if (aspect != 1) {
int newWidth = image.getWidth() / aspect;
int newHeight = image.getHeight() / aspect;
byte[] scaledBitmapData = bitmapToByteArray(createScaledBitmap(bao.toByteArray(), newWidth, newHeight));
bao = new ByteArrayOutputStream(scaledBitmapData.length);
bao.write(scaledBitmapData, 0 , scaledBitmapData.length);
image.compressToJpeg(new Rect(0, 0, newWidth, newHeight), jpegQuality, bao);
}
Utility methods:
public static Bitmap createScaledBitmap(byte[] bitmapAsData, int width, int height) {
Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapAsData, 0, bitmapAsData.length);
return createScaledBitmap(bitmap, width, height);
}
public static Bitmap createScaledBitmap(Bitmap bitmap, int width, int height) {
return Bitmap.createScaledBitmap(bitmap, width, height, true);
}
public static byte[] bitmapToByteArray(Bitmap bitmap) {
ByteArrayOutputStream blob = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, JPEG_QUALITY, blob);
return blob.toByteArray();
}
And this should do the trick.