如何解决如何使用 Camera2 API 重新打开相机?
我正在使用 Camera2 API 创建自定义相机。我想在使用相机预览(继续捕获图像)保存图像后重新打开相机。我尝试在保存图像后重新打开相机,但显示错误。
android.view.ViewRootImpl$CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触摸其视图。
private final TextureView.SurfaceTextureListener mSurfaceTextureListener
= new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture texture,int width,int height) {
openCamera(width,height);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture texture,int height) {
configureTransform(width,height);
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture texture) {
}
};
打开相机方法
private void openCamera(int width,int height) {
if (ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
requestCameraPermission();
return;
}
setUpCameraOutputs(width,height);
configureTransform(width,height);
Activity activity = getActivity();
CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
try {
if (!mCameraOpenCloseLock.tryAcquire(2500,TimeUnit.MILLISECONDS)) {
throw new RuntimeException("Time out waiting to lock camera opening.");
}
manager.openCamera(mCameraId,mStateCallback,mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
} catch (InterruptedException e) {
throw new RuntimeException("Interrupted while trying to lock camera opening.",e);
}
}
重新打开相机方法
public void reopenCamera() {
Log.d("REOPENCAMERA","reopenCamera: called.");
if (mTextureView.isAvailable()) {
Log.d(TAG,"reopenCamera: a surface is available.");
if(stillCapturedImage){
capture++;
changeFrame(capture);
openCamera(mTextureView.getWidth(),mTextureView.getHeight());
}else{
openCamera(mTextureView.getWidth(),mTextureView.getHeight());
}
} else {
Log.d(TAG,"reopenCamera: no surface is available.");
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
}
}
捕获会话
private CameraCaptureSession.CaptureCallback mCaptureCallback
= new CameraCaptureSession.CaptureCallback() {
private void process(CaptureResult result) {
switch (mState) {
case STATE_PREVIEW: {
// We have nothing to do when the camera preview is working normally.
break;
}
case STATE_WAITING_LOCK: {
Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
if (afState == null) {
captureStillPicture();
} else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
// CONTROL_AE_STATE can be null on some devices
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null ||
aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
mState = STATE_PICTURE_TAKEN;
captureStillPicture();
} else {
runPrecaptureSequence();
}
}
else if(afState == CaptureResult.CONTROL_AF_STATE_INACTIVE){
mState = STATE_PICTURE_TAKEN;
captureStillPicture();
}
break;
}
case STATE_WAITING_PRECAPTURE: {
// CONTROL_AE_STATE can be null on some devices
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null ||
aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
mState = STATE_WAITING_NON_PRECAPTURE;
}
break;
}
case STATE_WAITING_NON_PRECAPTURE: {
// CONTROL_AE_STATE can be null on some devices
Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
mState = STATE_PICTURE_TAKEN;
captureStillPicture();
}
break;
}
}
}
@Override
public void onCaptureProgressed(@NonNull CameraCaptureSession session,@NonNull CaptureRequest request,@NonNull CaptureResult partialResult) {
process(partialResult);
}
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session,@NonNull TotalCaptureResult result) {
process(result);
}
};
保存图片方法
private void saveTempImageToStorage(){
Log.d(TAG,"saveTempImageToStorage: saving temp image to disk.");
final ICallback callback = new ICallback() {
@Override
public void done(Exception e) {
if(e == null){
Log.d(TAG,"onImageSavedCallback: image saved!");
mBackgroundImageRotater = new BackgroundImageRotater(getActivity());
mBackgroundImageRotater.execute();
mIsImageAvailable = true;
mCapturedImage.close();
}
else{
Log.d(TAG,"onImageSavedCallback: error saving image: " + e.getMessage());
showSnackBar("Error displaying image",Snackbar.LENGTH_SHORT);
}
}
};
ImageSaver imageSaver = new ImageSaver(
mCapturedImage,getActivity().getExternalFilesDir(null),callback
);
mBackgroundHandler.post(imageSaver);
}
解决方法
reopenCamera 方法应该没问题,但您需要将一些后台任务(更新您的 UI)移动到主线程。
示例代码:
#!/usr/bin/env python
import rospy
import math
from sensor_msgs.msg import LaserScan
from geometry_msgs.msg import Twist
from nav_msgs.msg import Odometry
from tf import transformations
from sensor_msgs.msg import LaserScan
subL_value = ''
subR_value = 'test'
def callbackLeft(msg) :
subL_value = min(msg.ranges[0:49])
def callbackRight(msg) :
global subR_value
subR_value = min(msg.ranges[0:49])
def run() :
# rospy.Subscriber('/scan_left',LaserScan,callbackLeft)
rospy.Subscriber('/scan_right',callbackRight)
# print('\tLeft: '),# print(subL_value)
print('\tRight: '),global subR_value
print(subR_value)
if __name__ == "__main__":
rospy.init_node('wall_detector')
run()
rospy.spin()
最后,请确保您正确使用生命周期方法。
找到更多信息版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。