0

我正在尝试用我的 android 应用程序做一些非常不同的事情:我需要以定时间隔(每 2 秒左右)将相机的图像作为位图抓取。我不希望它是实时的,因为一旦我拥有它,我需要在位图上运行几个繁重的进程,而且为了提高效率,我不想每秒运行几十次。我也不需要将它保存为文件,我只需要它在 currentBitmap 中。

这是我尝试实现的代码:

public class MainActivity extends Activity {

private Camera camera;
private CameraPreview camPreview;
private FrameLayout camLayout;

// The app will process the camera frame on intervals instead of constantly
private static final long PROCESS_TIME = 2000; //(in milliseconds)
private static final long START_TIME = 2000;
private Timer timer;

// I want the bitmap in this instance
private Bitmap currentBitmap;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    camLayout = (FrameLayout) findViewById(R.id.camera_preview);

    setupCameraPreview();

    // Set up the timer
    timer = new Timer();
    timer.schedule(new TimerTask() {            
        @Override
        public void run() {
            TimerMethod();
        }
    }, START_TIME, PROCESS_TIME);
}

private void TimerMethod()
{   // Run Timer_Action on the same thread as the UI
    this.runOnUiThread(Timer_Action);
}

private Runnable Timer_Action = new Runnable() {
    public void run() {

        // Process each bitmap here
        try {

            camera.takePicture(null, null, pictureCallback);

        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    Toast.makeText(getApplicationContext(), 
                        "Photo capture attempted", Toast.LENGTH_SHORT).show();
    }
};

private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {

        try {
            currentBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            Toast.makeText(getApplicationContext(), 
                    "Photo capture successful", Toast.LENGTH_SHORT).show();

        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    }
};


private void setupCameraPreview() {

    try {   // Try to initialize the camera
        camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);
        camPreview = new CameraPreview(this, camera);
        camLayout.addView(camPreview);

    } catch (Exception e) {
        e.printStackTrace();
        camera = null;
        camPreview = null;
    }
}

当我跑步时会发生什么,相机预览和计时器似乎运行良好。但是 pictureCallback、data[] 和 currentBitmap 都保持为空,因此 try 块抛出它们的异常并且应用程序继续运行。我的猜测是 pictureCallback 没有从相机获取数据,但我该如何解决呢?如果这不是问题,那是什么?

非常感谢所有帮助。

4

1 回答 1

0

不知道为什么pictureCallback没有正确初始化,我一般把这个回调声明为activity的一个方法,它实现了Camera.PictureCallback和/或Camera.PreviewCallback。

但是为了您的目的,如果您对预览分辨率感到满意,您可以通过计时器设置OneShotPreviewCallback,或者只是在您完成上一个缓冲区的处理时。

预览分辨率通常为 640×480,在当代功能强大的设备上可达 1080p。

在大多数手机和平板电脑上,回调只接收 YUV 图像,但有些可能配置为提供 RGB。无论如何,从 yuv 到 rgb 的转换应该不是问题(使用 Wikipedia 中的定点公式)。

于 2013-08-19T05:46:41.040 回答