调用 Camera.stopPreview() 时 SurfaceView 变黑

发布于 2024-11-30 17:15:32 字数 255 浏览 0 评论 0原文

我正在对相机捕获的预览进行一些图像处理。这是一个消耗 CPU 的任务,我必须停止预览才能加快速度。在处理新帧之前,我调用 Camera.stopPreview() 并在 Camera.startPreview() 之后调用。

但是,我希望在停止预览后在 SurfaceView 上显示最后捕获的帧。它在 2.3 设备上“开箱即用”,但是,在旧版本的 SDK 上调用 Camera.stopPreview() 后,SurfaceView 会变黑。有谁知道发生了什么变化以及该怎么办?

I am doing some image processing of previews captured by the camera. It is cpu consuming task and I have to stop preview to make it faster. Before new frame is being processed I am calling Camera.stopPreview() and after Camera.startPreview().

However, I would like to have last captured frame displayed on SurfaceView after stopping the preview. It works 'out of the box' on 2.3 devices, however, SurfaceView gets black after calling Camera.stopPreview() on older versions of SDK. Does anyone know what has changed and what to do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

七秒鱼° 2024-12-07 17:15:32

是的,这是 2.3 的改进。

我在 2.2 中也遇到了这个问题,尽管根据 API 理论上这是可能的,但无法处理预览图像。为了解决这个问题,我必须使用Camera.takePicture(null, null, Camera.PictureCallback myCallback)实际拍照(参见信息此处),然后实现回调来处理拍摄的图片。实现此回调的类的实例实际上是传递给 Camera.takePicture() 的参数,回调方法本身如下所示:

public void onPictureTaken(byte[] JPEGData, Camera camera) {
    final Bitmap bitmap = createBitmapFromView(JPEGData);

    // do something with the Bitmap
}

这样做可以防止将图片保存在外部存储上使用相机应用程序拍摄的常规照片。如果您需要序列化位图,则必须明确执行。但这并不能阻止相机触发声音的发出。

预览运行时必须调用Camera.takePicture()。之后可以立即调用 stopPreview()

需要注意的一件事是 /!\:

Camera.takePicture() 是不可重入的(根本)。回调必须在任何后续调用 Camera.takePicture() 之前返回。这让我的手机冻结了,我必须关闭并重新启动它才能再次使用。由于该操作是由按钮触发的,因此在我这边,我必须用布尔值来屏蔽它:

if (!mPictureTaken) {
    mPictureTaken = true; // absolutely NOT reentrant. Any double click sticks the phone otherwise.
    mCameraView.takePicture(callback);
}

Yes, this was an improvement of the 2.3.

I had this problem in 2.2 as well, there was no way to work on a preview image despite the fact this was theoretically possible according to the API. To solve this I had to actually take a picture using Camera.takePicture(null, null, Camera.PictureCallback myCallback) (see info here) and then to implement a callback to handle the taken picture. The instance of the class that implements this callback is actually the parameter to pass to Camera.takePicture() and the callback method itself looks like this:

public void onPictureTaken(byte[] JPEGData, Camera camera) {
    final Bitmap bitmap = createBitmapFromView(JPEGData);

    // do something with the Bitmap
}

Doing that way prevents the picture to be saved on the external storage with the regular pictures taken with the camera application. Should you need to serialize the Bitmap you'll have to do it explicitely. But it doesn't prevent the camera's trigger sound from being emitted.

Camera.takePicture() has to be called wile the preview is running. stopPreview() can be called right after.

One thing to be careful with /!\:

Camera.takePicture() is not reentrant (at all). The callback must have returned before any subsequent call of Camera.takePicture(). This was freezing my phone, I had to shutdown and restart it before it to be usable again. As the action was triggered by a button, on my side, I had to shield it with a boolean:

if (!mPictureTaken) {
    mPictureTaken = true; // absolutely NOT reentrant. Any double click sticks the phone otherwise.
    mCameraView.takePicture(callback);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文