编辑:我发现问题出现在onPreviewFrame函数中:
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
if (frameCount == 0) {
start = System.currentTimeMillis();
} else if (frameCount % 100 == 0) {
Log.e("FPS", 1000 * frameCount
/ (System.currentTimeMillis() - start) + "");
}
frameCount++;
Bitmap temp = BitmapFactory.decodeByteArray(data, 0, data.length);
try {
temp.compress(CompressFormat.JPEG, 90, new FileOutputStream(new File("/sdcard/"+frameCount+".jpg")));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
camera.addCallbackBuffer(data);
}
如果我删除了与Bitmap相关的所有代码,那么程序可以拍摄没有任何错误的图片。如何保存帧图像和使用Camera.takePicture生成的更好的图像? 当触摸按钮时,我尝试从相机保存照片,并开始另一个活动来编辑照片。
mTakePic.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
mTakePic.setImageDrawable(takePicDown);
mCamera.takePicture(new ShutterCallback() {
@Override
public void onShutter() {
// TODO Auto-generated method stub
}
}, null, new PictureCallback() {
@Override
public void onPictureTaken(byte[] yuv, Camera camera) {
Intent editImage = new Intent(getApplicationContext(), EditActivity.class);
if(savePhoto != null) {
try {
savePhoto.get();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
savePhoto = new SavePhotoTask();
savePhoto.execute(yuv);
// releaseCamera();
startActivity(editImage);
}
});
} else if (event.getAction() == MotionEvent.ACTION_UP) {
mTakePic.setImageDrawable(takePicUp);
}
return true;
}
});
有时它运行顺利没有错误,但大多数情况下它会导致错误,我必须重新启动手机才能让相机再次工作。我使用SurfaceView预览相机框架。
答案 0 :(得分:1)
编辑:对不起,我误解了这个问题,我以为你把你提到的崩溃链接到了SavePhotoTask。以下是如何保存PictureCallback
onPictureTaken
的第一个参数是包含图像的字节数组。只需将其写入文件就是我发现保存图像的最佳方式。像这样......
FileOutputStream out = new FileOutputStream("path/to/image");
out.write(data, 0, data.length);
out.close();
其中"数据"是来自onPictureTaken
的第一个arg。同样的技术应该可以保存onPreviewFrame
中的每一帧,但我从来没有尝试过,所以我无法确定。看起来你有想法把这个操作放在一个单独的线程上,这很好,我会继续探索这个选项。但是,我要避免使用Bitmap,因为这需要时间和资源,如果您同时转换多个帧并在内存中包含所有这些位图,则可能会导致OOM错误。
一旦您拨打Camera.open()
,您的应用就会锁定相机并阻止任何其他应用程序(包括您自己的应用程序的后续实例)使用它。当您的申请完成或相机将保持锁定状态时,必须致电Camera.release()
,直到您已经注意到电话重新启动为止。 The dev docs for the Camera has a good checklist to follow at the top in order to ensure the class gets used correctly.
我已成功拨打Camera.open()
中的onResume()
和Camera.release()
中的onPause()
。为了保持平稳和无错误,您可能还希望在这些点上管理您的开始和停止预览。