Skip to content Skip to sidebar Skip to footer

Convert CameraX Captured ImageProxy To Bitmap

I was working with CameraX and had hard time converting captured ImageProxy to Bitmap. After searching and trying, I formulated a solution. Later I found that it was not optimum so

Solution 1:

So the solution was to add extension method to Image and here is the code

class ImagePickerActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_image_picker)
    }

    private fun startCamera() {

        val imageCapture = ImageCapture(imageCaptureConfig)
        capture_button.setOnClickListener {

            imageCapture.takePicture(object : ImageCapture.OnImageCapturedListener() {
                override fun onCaptureSuccess(image: ImageProxy?, rotationDegrees: Int) {
                    imageView.setImageBitmap(image.image?.toBitmap())
                }
                //.....
            })
        }
    }

}

fun Image.toBitmap(): Bitmap {
    val buffer = planes[0].buffer
    buffer.rewind()
    val bytes = ByteArray(buffer.capacity())
    buffer.get(bytes)
    return BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
}

Solution 2:

Slightly modified version. Using the inline function use on the Closable ImageProxy

imageCapture.takePicture(
           object : ImageCapture.OnImageCapturedListener() {
               override fun onCaptureSuccess(image: ImageProxy?, rotationDegrees: Int) {
                     image.use { image ->
                           val bitmap: Bitmap? = image?.let {
                                imageProxyToBitmap(it)
                            } ?: return
                      }
          }
       })

  private fun imageProxyToBitmap(image: ImageProxy): Bitmap {
        val buffer: ByteBuffer = image.planes[0].buffer
        val bytes = ByteArray(buffer.remaining())
        buffer.get(bytes)
        return BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
    } 

Solution 3:

Java Implementation of Backbelt's Answer.

private Bitmap imageProxyToBitmap(ImageProxy image) {
    ByteBuffer buffer = image.getPlanes()[0].getBuffer();
    byte[] bytes = new byte[buffer.remaining()];
    buffer.get(bytes);
    return BitmapFactory.decodeByteArray(bytes,0,bytes.length,null);
}

Solution 4:

Here is the safest approach, using MLKit's own implementation. Tested and working on MLKit version 1.0.1

import com.google.mlkit.vision.common.internal.ImageConvertUtils;

Image mediaImage = imageProxy.getImage();
InputImage image = InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees());
Bitmap bitmap = ImageConvertUtils.getInstance().getUpRightBitmap(image)

Solution 5:

There is second version of takePicture method at the moment (CameraX version 1.0.0-beta03). It provides several ways to persist image (OutputStream or maybe File can be useful in your case).

If you still want to convert ImageProxy to Bitmap here is my answer to similar question, which gives the correct implemetation of this conversion.


Post a Comment for "Convert CameraX Captured ImageProxy To Bitmap"