You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android CameraX(Java)Image转Bitmap数组越界问题求助

Fix ArrayIndexOutOfBoundsException When Converting ImageProxy to Bitmap in CameraX (Java)

Hey there, let's break down why you're hitting that ArrayIndexOutOfBoundsException and fix it with reliable Java solutions.

What's Causing the Issue?

Your current toBitmap method assumes the image uses the YUV_420_888 format (which has 3 separate planes), but CameraX might be returning a single-plane format like JPEG depending on your ImageCapture setup. That’s why image.getPlanes().length is 1 instead of 3—your code tries to access indexes 1 and 2 which don’t exist, triggering the error.

Solution 1: Handle Multiple Image Formats in toBitmap

Update your conversion method to check the image format first, then handle both YUV_420_888 and JPEG formats properly:

private Bitmap toBitmap(Image image) {
    if (image.getFormat() == ImageFormat.YUV_420_888) {
        // Process 3-plane YUV_420_888 format
        Image.Plane[] planes = image.getPlanes();
        ByteBuffer yBuffer = planes[0].getBuffer();
        ByteBuffer uBuffer = planes[1].getBuffer();
        ByteBuffer vBuffer = planes[2].getBuffer();

        int ySize = yBuffer.remaining();
        int uSize = uBuffer.remaining();
        int vSize = vBuffer.remaining();

        byte[] nv21 = new byte[ySize + uSize + vSize];

        // Copy Y plane data
        yBuffer.get(nv21, 0, ySize);
        // Swap and copy V/U planes for NV21 compatibility
        vBuffer.get(nv21, ySize, vSize);
        uBuffer.get(nv21, ySize + vSize, uSize);

        YuvImage yuvImage = new YuvImage(nv21, ImageFormat.NV21, image.getWidth(), image.getHeight(), null);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        yuvImage.compressToJpeg(new Rect(0, 0, image.getWidth(), image.getHeight()), 75, out);
        byte[] imageBytes = out.toByteArray();
        return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
    } else if (image.getFormat() == ImageFormat.JPEG) {
        // Process single-plane JPEG format
        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
        byte[] imageBytes = new byte[buffer.remaining()];
        buffer.get(imageBytes);
        return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
    } else {
        // Fallback for unsupported formats
        throw new IllegalArgumentException("Unsupported image format: " + image.getFormat());
    }
}

Critical Reminder: Always Close ImageProxy

After processing the image, call image.close() to release system resources and avoid memory leaks. Update your onCaptureSuccess method:

@Override
public void onCaptureSuccess(ImageProxy image, int rotationDegrees) {
    try {
        Bitmap bitmap = rotateImage(toBitmap(image.getImage()), (float) rotationDegrees);
        ImageView takenImage.setImageBitmap(bitmap);
    } finally {
        // Mandatory: Close the ImageProxy to free resources
        image.close();
    }
    super.onCaptureSuccess(image, rotationDegrees);
}

Alternative Solution: File-Based Capture (Simpler)

If you don’t need in-memory image processing right away, use CameraX’s file-based capture to skip manual format handling entirely. This is more efficient and avoids format-related bugs:

private void takePicture() {
    // Create a temporary file to store the photo
    File photoFile = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "photo_" + System.currentTimeMillis() + ".jpg");

    ImageCapture.OutputFileOptions outputOptions = new ImageCapture.OutputFileOptions.Builder(photoFile).build();

    imageCapture.takePicture(outputOptions, ContextCompat.getMainExecutor(this), new ImageCapture.OnImageSavedCallback() {
        @Override
        public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
            // Load bitmap from the saved file
            Bitmap bitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
            // Rotate bitmap to match device orientation
            Bitmap rotatedBitmap = rotateImage(bitmap, getScreenRotationDegrees());
            takenImage.setImageBitmap(rotatedBitmap);
        }

        @Override
        public void onError(@NonNull ImageCaptureException exception) {
            Log.e("CameraX", "Capture failed: " + exception.getMessage());
        }
    });
}

// Helper to get correct rotation based on screen orientation
private float getScreenRotationDegrees() {
    int rotation = getWindowManager().getDefaultDisplay().getRotation();
    return rotation * 90f;
}

内容的提问来源于stack exchange,提问作者Prajwal Bhat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 16:42:37