ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

android-使用camera2 API获取单个图像并使用ImageView显示

2019-11-11 15:26:29  阅读:221  来源: 互联网

标签:android-camera2 android


我想使用Camera2 API从相机中获取单个帧并使用ImageView显示它.
我发现了一些密切的问题,例如

https://stackoverflow.com/questions/25462277/camera-preview-image-data-processing-with-android-l-and-camera2-api

而且我也看过Camera2Basic示例,但是它太复杂了,并不是我真正需要的.

我写的代码是基于我在网络上看到的一些示例,应该可以执行,但无法正常工作,我不知道为什么.

该应用程序不会崩溃,但不会在ImageView上显示任何内容.
我在任何函数调用中都使用了Log消息,以尝试使logcat保持清晰.

另外,该应用程序的logcat表示“该应用程序可能在后台执行了太多工作.”我看不到这是怎么回事,因为我发出了单个captureRequest而不是RepeatingCaptureRequest.

这是代码和logcat:
码:

public class CameraImageReaderActivity extends AppCompatActivity {

private final static String TAG = "CAMERA_IMAGE_READY: ";
private ImageReader imageReader;
private String cameraId;
private CameraDevice camera;
private HandlerThread handlerThread;
private Handler handler;
private Surface imageReaderSurface;
private ImageView imageView;

private CameraDevice.StateCallback cameraStateCallback = new CameraDevice.StateCallback() {
    @Override
    public void onOpened(CameraDevice cameraDevice) {
        Log.d(TAG, "onOpend: CAMERA OPENED");
        camera = cameraDevice;
        getFrames();
    }

    @Override
    public void onDisconnected(CameraDevice cameraDevice) {
        Log.d(TAG, "onDisconnected: CAMERA DISCONNECTED");
        cameraDevice.close();
        camera = null;
    }

    @Override
    public void one rror(CameraDevice cameraDevice, int i) {
        Log.d(TAG, "onError: CAMERA ERROR");
        cameraDevice.close();
        camera = null;
    }
};

private CameraCaptureSession.StateCallback captureSessionStateCallback = new CameraCaptureSession.StateCallback() {
    @Override
    public void onConfigured(CameraCaptureSession cameraCaptureSession) {
        Log.d(TAG, "onConfigured: build request and capture");
        try {
            CaptureRequest.Builder requestBuilder = cameraCaptureSession.getDevice().createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
            requestBuilder.addTarget(imageReaderSurface);

            cameraCaptureSession.capture(requestBuilder.build(), null, handler);
        } catch (CameraAccessException e) {
            Log.d(TAG, "onConfigured: CANT CREATE CAPTURE REQUEST");
            e.printStackTrace();
        }
    }

    @Override
    public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
        Log.d(TAG, "onConfiguredFailed: CANT CONFIGURE CAMERA");
    }
};

private ImageReader.OnImageAvailableListener imageReaderListener = new ImageReader.OnImageAvailableListener() {
    @Override
    public void onImageAvailable(ImageReader imageReader) {
        Log.d(TAG, "onImageAvailable: IMAGE AVAILABLE");
        Image image = imageReader.acquireLatestImage();
        int imgFormat = image.getFormat();
        ByteBuffer pixelArray1 = image.getPlanes()[0].getBuffer();
        int pixelStride = image.getPlanes()[0].getPixelStride();
        int rowStride = image.getPlanes()[0].getRowStride();
        int rowPadding = rowStride - pixelStride * 640;

        Bitmap bitmap = Bitmap.createBitmap(640 + rowPadding/pixelStride, 480, Bitmap.Config.RGB_565);
        bitmap.copyPixelsFromBuffer(pixelArray1);
        imageView.setImageBitmap(bitmap);

        image.close();
    }
};

/**
 * Sets the cameraId with the front camera id and sets imageReader properties.
 */
public void setupCamera(int width, int height) {
    imageReader = ImageReader.newInstance(width, height, ImageFormat.RGB_565, 30);
    CameraManager cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);
    try {
        for (String allCamerasId : cameraManager.getCameraIdList()) {
            CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(allCamerasId);
            if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) {
                continue;
            }
            cameraId = allCamerasId;
            Log.d(TAG, "setupCamera: CameraId is: " + cameraId);
            return;
        }
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }

}

/**
 * Connects to the front facing camera.
 * After the connection to the camera, the onOpened callback method will be invoked.
 */
public void connectCamera() {
    CameraManager cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);
    try {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG, "CANT OPEN CAMERA");
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        cameraManager.openCamera(cameraId, cameraStateCallback, handler);
        Log.d(TAG, "connectCamera: CAMERA OPENED!");
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

/**
 * Build the captureSessionRequest and start in repeat.
 */
public void getFrames() {
    Log.d(TAG, "getFrames: CREATE CAPTURE SESSION");
    imageReaderSurface = imageReader.getSurface();
    List<Surface> surfaceList = new ArrayList<>();
    surfaceList.add(imageReaderSurface);
    try {
        camera.createCaptureSession(surfaceList, captureSessionStateCallback, handler);
    } catch (CameraAccessException e) {
        e.printStackTrace();
    }
}

public void startBackgroundThread() {
    handlerThread = new HandlerThread("CameraImageReaderActivity");
    handlerThread.start();
    handler = new Handler(handlerThread.getLooper());
}

public void stopBackgroundThread() {
    handlerThread.quitSafely();
    try {
        handlerThread.join();
        handlerThread = null;
        handler = null;
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

public void closeCamera() {
    if (camera != null) {
        camera.close();
        camera = null;
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_camera_image_reader);
    imageView = (ImageView) findViewById(R.id.imageView);
    setupCamera(640, 480);
    connectCamera();
}

@Override
protected void onPause() {
    closeCamera();
    startBackgroundThread();
    super.onPause();
}

@Override
protected void onResume() {
    super.onResume();
    startBackgroundThread();
    //connectCamera();
}

和(相关的)logcat:

03-22 14:27:32.900 18806-18806/com.example.noamm_000.talkwithcompviawifi D/CAMERA_IMAGE_READY:: setupCamera: CameraId is: 0
03-22 14:27:32.904 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value mw_continuous-picture
03-22 14:27:32.905 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value emboss
03-22 14:27:32.905 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value sketch
03-22 14:27:32.905 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value neon
03-22 14:27:32.905 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value asd
03-22 14:27:32.905 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value backlight
03-22 14:27:32.905 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value flowers
03-22 14:27:32.905 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value AR
03-22 14:27:32.912 18806-18806/com.example.noamm_000.talkwithcompviawifi I/CameraManager: Using legacy camera HAL.
03-22 14:27:33.685 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value mw_continuous-picture
03-22 14:27:33.685 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value emboss
03-22 14:27:33.685 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value sketch
03-22 14:27:33.685 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value neon
03-22 14:27:33.686 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value asd
03-22 14:27:33.686 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value backlight
03-22 14:27:33.686 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value flowers
03-22 14:27:33.686 18806-18806/com.example.noamm_000.talkwithcompviawifi W/ArrayUtils: Ignoring invalid value AR
03-22 14:27:33.702 18806-18806/com.example.noamm_000.talkwithcompviawifi D/CAMERA_IMAGE_READY:: connectCamera: CAMERA OPENED!
03-22 14:27:33.719 18806-18806/com.example.noamm_000.talkwithcompviawifi I/Choreographer: Skipped 56 frames!  The application may be doing too much work on its main thread.
03-22 14:27:33.787 18806-18806/com.example.noamm_000.talkwithcompviawifi D/CAMERA_IMAGE_READY:: onOpend: CAMERA OPENED
03-22 14:27:33.787 18806-18806/com.example.noamm_000.talkwithcompviawifi D/CAMERA_IMAGE_READY:: getFrames: CREATE CAPTURE SESSION
03-22 14:27:33.789 18806-18806/com.example.noamm_000.talkwithcompviawifi I/CameraDeviceState: Legacy camera service transitioning to state CONFIGURING
03-22 14:27:33.789 18806-19149/com.example.noamm_000.talkwithcompviawifi I/RequestThread-0: Configure outputs: 1 surfaces configured.
03-22 14:27:33.790 18806-19149/com.example.noamm_000.talkwithcompviawifi D/Camera: app passed NULL surface
03-22 14:27:33.838 18806-18806/com.example.noamm_000.talkwithcompviawifi I/CameraDeviceState: Legacy camera service transitioning to state IDLE
03-22 14:27:33.843 18806-19150/com.example.noamm_000.talkwithcompviawifi D/CAMERA_IMAGE_READY:: onConfigured: build request and capture
03-22 14:27:33.874 18806-19149/com.example.noamm_000.talkwithcompviawifi W/LegacyRequestMapper: convertRequestMetadata - control.awbRegions setting is not supported, ignoring value
03-22 14:27:33.875 18806-19149/com.example.noamm_000.talkwithcompviawifi W/LegacyRequestMapper: Only received metering rectangles with weight 0.
03-22 14:27:33.875 18806-19149/com.example.noamm_000.talkwithcompviawifi W/LegacyRequestMapper: Only received metering rectangles with weight 0.
03-22 14:27:34.070 18806-18806/com.example.noamm_000.talkwithcompviawifi I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@13c07070 time:331143683
03-22 14:27:34.317 18806-19155/com.example.noamm_000.talkwithcompviawifi I/CameraDeviceState: Legacy camera service transitioning to state CAPTURING
03-22 14:27:34.353 18806-19149/com.example.noamm_000.talkwithcompviawifi I/CameraDeviceState: Legacy camera service transitioning to state IDLE
03-22 14:27:34.403 18806-18806/com.example.noamm_000.talkwithcompviawifi D/BubblePopupHelper: isShowingBubblePopup : false
03-22 14:27:34.403 18806-18806/com.example.noamm_000.talkwithcompviawifi D/BubblePopupHelper: isShowingBubblePopup : false
03-22 14:27:34.404 18806-18806/com.example.noamm_000.talkwithcompviawifi D/BubblePopupHelper: isShowingBubblePopup : false
03-22 14:27:34.404 18806-18806/com.example.noamm_000.talkwithcompviawifi D/BubblePopupHelper: isShowingBubblePopup : false
03-22 14:28:07.684 18806-18823/com.example.noamm_000.talkwithcompviawifi E/BufferQueueProducer: [unnamed-18806-1] cancelBuffer: BufferQueue has been abandoned
03-22 14:28:07.684 18806-18822/com.example.noamm_000.talkwithcompviawifi E/BufferQueueProducer: [unnamed-18806-1] cancelBuffer: BufferQueue has been abandoned
03-22 14:28:07.684 18806-19184/com.example.noamm_000.talkwithcompviawifi E/BufferQueueProducer: [unnamed-18806-1] cancelBuffer: BufferQueue has been abandoned
03-22 14:28:07.685 18806-18823/com.example.noamm_000.talkwithcompviawifi E/BufferQueueProducer: [unnamed-18806-1] cancelBuffer: BufferQueue has been abandoned
03-22 14:28:07.685 18806-18822/com.example.noamm_000.talkwithcompviawifi E/BufferQueueProducer: [unnamed-18806-1] cancelBuffer: BufferQueue has been abandoned
03-22 14:28:07.685 18806-19184/com.example.noamm_000.talkwithcompviawifi E/BufferQueueProducer: [unnamed-18806-1] cancelBuffer: BufferQueue has been abandoned
03-22 14:28:07.686 18806-18823/com.example.noamm_000.talkwithcompviawifi E/BufferQueueProducer: [unnamed-18806-1] cancelBuffer: BufferQueue has been abandoned
03-22 14:28:07.686 18806-18822/com.example.noamm_000.talkwithcompviawifi E/BufferQueueProducer: [unnamed-18806-1] cancelBuffer: BufferQueue has been abandoned

谢谢,
诺姆

解决方法:

尝试这种方式更好地在后台线程中处理它.

 public void onImageAvailable(ImageReader reader) {
        new ImageSaver(reader.acquireLatestImage());
    } 

   private class ImageSaver implements Runnable {

        private final Image mImage;

        public ImageSaver(Image image) {
            mImage = image;
        }

        @Override
        public void run() {
            File mImageFileName = null;
            if (mImage != null) {

                ByteBuffer byteBuffer = mImage.getPlanes()[0].getBuffer();
                byte[] bytes = new byte[byteBuffer.remaining()];
                byteBuffer.get(bytes);

                FileOutputStream fileOutputStream = null;
                try {
                    mImageFileName = createImageFileName();
                    fileOutputStream = new FileOutputStream(mImageFileName);
                    fileOutputStream.write(bytes);
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    mImage.close();
                    if (mImageFileName != null) {
                        Intent mediaStoreUpdateIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
                        mediaStoreUpdateIntent.setData(Uri.fromFile(mImageFileName));
                        sendBroadcast(mediaStoreUpdateIntent);
                        loadImageFromStorage(mImageFileName);
                    }
                    if (fileOutputStream != null) {
                        try {
                            fileOutputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

        private void loadImageFromStorage(File mImageFileName) {
            imageView.setImageBitmap(BitmapFactory.decodeFile(mImageFileName.getAbsolutePath()));
        }
    }

    private File createImageFileName() throws IOException {
        String timestamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String prepend = "IMAGE_" + timestamp + "_";
        File imageFile = File.createTempFile(prepend, ".jpg", createImageFolder());
        return imageFile;
    }

    private File createImageFolder() {
        File imageFile = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File mImageFolder = new File(imageFile, "myFolder");
        if (!mImageFolder.exists()) {
            mImageFolder.mkdirs();
        }
        return mImageFolder;
    }

标签:android-camera2,android
来源: https://codeday.me/bug/20191111/2020803.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有