Question

please tell me how can I resize yuv image on android.

ByteArrayOutputStream baos = new ByteArrayOutputStream();
mCameraView.myuvImage.compressToJpeg(new Rect(0, 0, mCameraView.myuvImage.getWidth(), mCameraView.myuvImage.getHeight()), 100, baos);

compressToJpeg method converts yuv image to jpeg. But doesn't resize converted JPEG by compression number when I write

mCameraView.myuvImage.compressToJpeg(new Rect(0, 0, mCameraView.myuvImage.getWidth(), mCameraView.myuvImage.getHeight()), 50, baos);
Was it helpful?

Solution

The easiest way would be to create a scaled bitmap. First, convert your bitmap to a bitmap image:

ByteArrayOutputStream out = new ByteArrayOutputStream();
YuvImage yuvImage = new YuvImage(mCameraView.myuvImage, PictureFormat.NV21, width, height, null);
yuvImage.compressToJpeg(new Rect(0, 0, width, height), 50, out);
byte[] imageBytes = out.toByteArray();
Bitmap image = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);

Then, you can resize with:

Bitmap resized = Bitmap.createScaledBitmap(image, newWidth, newHeight, true);

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top