bub*_*ubo 39 camera android image-processing preview android-5.0-lollipop
我正在开发一个Android应用程序,它正在处理来自摄像头的输入图像并将其显示给用户.这很简单,我PreviewCallback在相机对象上注册了一个setPreviewCallbackWithBuffer.这很简单,并且可以与旧的相机API一起使用
public void onPreviewFrame(byte[] data, Camera cam) {
// custom image data processing
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试移植我的应用程序以利用新的Camera2 API,我不确定我该怎么做.我在L预览示例中使用了Camera2Video,可以录制视频.但是,样本中没有直接的图像数据传输,因此我不明白应该在何处获取图像像素数据以及如何处理它.
有人可以帮我或建议如何获得PreviewCallbackandroid L 的功能,或者如何在将其显示到屏幕之前处理相机的预览数据?(相机对象上没有预览回调)
谢谢!
VP.*_*VP. 27
由于Camera2API与当前CameraAPI 非常不同,因此阅读文档可能会有所帮助.
一个很好的起点就是camera2basic例子.它演示了如何使用Camera2API并配置ImageReader获取JPEG图像并注册ImageReader.OnImageAvailableListener以接收这些图像
要接收预览画面,您需要将您添加ImageReader的表面setRepeatingRequest的CaptureRequest.Builder.
此外,您应该将ImageReader格式设置为YUV_420_888,这将在8MP时为您提供30fps(文档保证在8MP时为Nexus 5提供30fps).
Ang*_*loS 26
将一些答案组合成一个更容易消化的答案,因为@ VP的答案虽然技术上很清楚,但如果你是第一次从Camera转到Camera2那么很难理解:
使用https://github.com/googlesamples/android-Camera2Basic作为起点,修改以下内容:
在createCameraPreviewSession()初始化一个新Surface的mImageReader
Surface mImageSurface = mImageReader.getSurface();
Run Code Online (Sandbox Code Playgroud)
将该新曲面添加为CaptureRequest.Builder变量的输出目标.使用Camera2Basic示例,变量将是mPreviewRequestBuilder
mPreviewRequestBuilder.addTarget(mImageSurface);
Run Code Online (Sandbox Code Playgroud)
这是带有新行的片段(请参阅我的@AngeloS评论):
private void createCameraPreviewSession() {
try {
SurfaceTexture texture = mTextureView.getSurfaceTexture();
assert texture != null;
// We configure the size of default buffer to be the size of camera preview we want.
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
// This is the output Surface we need to start preview.
Surface surface = new Surface(texture);
//@AngeloS - Our new output surface for preview frame data
Surface mImageSurface = mImageReader.getSurface();
// We set up a CaptureRequest.Builder with the output Surface.
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
//@AngeloS - Add the new target to our CaptureRequest.Builder
mPreviewRequestBuilder.addTarget(mImageSurface);
mPreviewRequestBuilder.addTarget(surface);
...
Run Code Online (Sandbox Code Playgroud)
接下来,在setUpCameraOutputs(),格式从改变ImageFormat.JPEG到ImageFormat.YUV_420_888,当你初始化你的ImageReader.(PS,我还建议删除预览尺寸,以便更顺畅地操作 - Camera2的一个不错的功能)
mImageReader = ImageReader.newInstance(largest.getWidth() / 16, largest.getHeight() / 16, ImageFormat.YUV_420_888, 2);
Run Code Online (Sandbox Code Playgroud)
最后,在你的onImageAvailable()方法中ImageReader.OnImageAvailableListener,一定要使用@Kamala的建议,因为如果不关闭它,预览将在几帧后停止
@Override
public void onImageAvailable(ImageReader reader) {
Log.d(TAG, "I'm an image frame!");
Image image = reader.acquireNextImage();
...
if (image != null)
image.close();
}
Run Code Online (Sandbox Code Playgroud)
小智 14
在ImageReader.OnImageAvailableListener类中,读取后关闭图像,如下所示(这将释放缓冲区以进行下一次捕获).您必须在关闭时处理异常
Image image = imageReader.acquireNextImage();
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
image.close();
Run Code Online (Sandbox Code Playgroud)
我需要相同的东西,所以我使用他们的例子,并在相机处于预览状态时添加了对新功能的调用.
private CameraCaptureSession.CaptureCallback mCaptureCallback
= new CameraCaptureSession.CaptureCallback()
private void process(CaptureResult result) {
switch (mState) {
case STATE_PREVIEW: {
if (buttonPressed){
savePreviewShot();
}
break;
}
Run Code Online (Sandbox Code Playgroud)
该savePreviewShot()仅仅是原来的再生版本captureStillPicture()适用于使用预览模板.
private void savePreviewShot(){
try {
final Activity activity = getActivity();
if (null == activity || null == mCameraDevice) {
return;
}
// This is the CaptureRequest.Builder that we use to take a picture.
final CaptureRequest.Builder captureBuilder =
mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
captureBuilder.addTarget(mImageReader.getSurface());
// Orientation
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation));
CameraCaptureSession.CaptureCallback CaptureCallback
= new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
TotalCaptureResult result) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss:SSS");
Date resultdate = new Date(System.currentTimeMillis());
String mFileName = sdf.format(resultdate);
mFile = new File(getActivity().getExternalFilesDir(null), "pic "+mFileName+" preview.jpg");
Log.i("Saved file", ""+mFile.toString());
unlockFocus();
}
};
mCaptureSession.stopRepeating();
mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
} catch (Exception e) {
e.printStackTrace();
}
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
34032 次 |
| 最近记录: |