我正在使用Android camera2 API.
我可以在手动对焦模式下使用LENS_FOCUS_DISTANCE获得焦距值.但是,AF模式下的属性始终为零.在AF模式下有没有办法获得焦距?
我正在尝试使用camera2 API创建一个从服务中获取一些照片的应用.
我可以让应用程序从基于Camera2Basic样本的片段中拍摄出精美的照片.
但是当我尝试移动到服务时,图像无法正确捕获.它永远不会超过自动曝光预捕获状态.
我把它缩小到没有预览的问题.我通过采用Camera2Basic代码并删除预览来组合测试片段,这导致了同样的问题.
我把一个有问题的测试片段放在一起,基于Camera2Basic样本,我基本上只删除了预览代码.片段代码上传到http://pastebin.ca/3182401.
我正在获取onCaptureCompleted()回调,但是当我在这里检查相机自动曝光状态时,它仍然处于CONTROL_AE_STATE_PRECAPTURE状态.
如果其中一个摄像机状态仍处于预先捕获状态,则捕获将完成对我来说没有意义.
有人知道这里会发生什么吗?
我正在尝试使用Camera2API将相机数据流式传输到SurfaceView.我正在按照本指南:Camera2指南
我无法过去 step 5
MainActivity.java::onCreate()
setContentView(R.layout.activity_main);
surfaceView = (SurfaceView)findViewById(R.id.surface);
manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE);
Run Code Online (Sandbox Code Playgroud)
MainActivity.java::onClick()
for (String id : manager.getCameraIdList()) {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(id);
Integer direction = characteristics.get(CameraCharacteristics.LENS_FACING);
if (direction != null && direction == CameraCharacteristics.LENS_FACING_BACK) {
if (checkCallingOrSelfPermission("android.permission.CAMERA") == PackageManager.PERMISSION_GRANTED)
manager.openCamera(id, new StateCallback(), null);
break;
}
}
Run Code Online (Sandbox Code Playgroud)
MainActivity.java.StateCallback :: onOpened(CameraDevice摄像头)
List<Surface> surfaces = new LinkedList<>();
surfaces.add(surfaceView.getHolder().getSurface());
CaptureRequest.Builder builder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
builder.addTarget(surfaces.get(0));
camera.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
Log.i(TAG, "Configured");
}
@Override …Run Code Online (Sandbox Code Playgroud) 我正在使用OnImageAvailableListener获取预览帧:
@Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try {
image = reader.acquireLatestImage();
Image.Plane[] planes = image.getPlanes();
ByteBuffer buffer = planes[0].getBuffer();
byte[] data = new byte[buffer.capacity()];
buffer.get(data);
//data.length=332803; width=3264; height=2448
Log.e(TAG, "data.length=" + data.length + "; width=" + image.getWidth() + "; height=" + image.getHeight());
//TODO data processing
} catch (Exception e) {
e.printStackTrace();
}
if (image != null) {
image.close();
}
}
Run Code Online (Sandbox Code Playgroud)
每次数据长度不同但图像宽度和高度相同.
主要问题:data.length对于3264x2448这样的分辨率来说太小了.
数据阵列的大小应为3264*2448 = 7,990,272,而不是300,000 - 600,000.
怎么了?
imageReader = ImageReader.newInstance(3264, …Run Code Online (Sandbox Code Playgroud) 有人可能我做错了...我想用SurfaceView捕获我有预览屏幕的图像.我能够在表面视图上显示预览.
这是我捕获图像的代码
if (mCameraSession == null && mCameraDevice == null) return;
ImageReader reader = ImageReader.newInstance(mTexturePreviewSize.getWidth(),
mTexturePreviewSize.getHeight(),
ImageFormat.JPEG, 1);
reader.setOnImageAvailableListener(imageAvailableListener, mBackgroundHandler);
Surface surface = reader.getSurface();
try {
CaptureRequest.Builder requestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
requestBuilder.addTarget(surface);
mCameraSession.capture(requestBuilder.build(), sessionCaptureListener, null);
Run Code Online (Sandbox Code Playgroud)
以下是我收到的错误消息.
java.lang.IllegalArgumentException: Bad argument passed to camera service
at android.hardware.camera2.utils.CameraBinderDecorator.throwOnError(CameraBinderDecorator.java:114)
at android.hardware.camera2.utils.CameraBinderDecorator$CameraBinderDecoratorListener.onAfterInvocation(CameraBinderDecorator.java:73)
at android.hardware.camera2.utils.Decorator.invoke(Decorator.java:81)
at java.lang.reflect.Proxy.invoke(Proxy.java:397)
at $Proxy2.submitRequestList(Unknown Source)
at android.hardware.camera2.impl.CameraDeviceImpl.submitCaptureRequest(CameraDeviceImpl.java:617)
at android.hardware.camera2.impl.CameraDeviceImpl.capture(CameraDeviceImpl.java:503)
at android.hardware.camera2.impl.CameraCaptureSessionImpl.capture(CameraCaptureSessionImpl.java:161)
at Control.CameraApi21Plus.captureSinglePhoto(CameraApi21Plus.java:171)
at com.CameraActivity$2.onClick(CameraActivity.java:108)
Run Code Online (Sandbox Code Playgroud)
捕获单个照片功能:
public void captureSinglePhoto() {
if (mCameraSession == null && mCameraDevice == null) return;
ImageReader reader = …Run Code Online (Sandbox Code Playgroud) 我们使用camera2 API使用mediacodec同时预览和编码视频.我们知道什么时候应该通过查询'CameraCharacteristics.SENSOR_ORIENTATION'来旋转相机,但只有预览旋转选项.
我们需要的是旋转到编码器的表面,这样我们就不会将视频颠倒过来.(或者像旧相机API一样旋转相机本身.)
谢谢
嗨,我正在使用camera2basic示例来实现我的camera2应用程序.我找不到任何好的例子来实现触摸以使用camera2 api进行聚焦.目前我用于触控的代码是:
private void setFocusArea(MotionEvent event) {
if (mCameraId == null) return;
CameraManager cm = (CameraManager)getActivity().getSystemService(Context.CAMERA_SERVICE);
CameraCharacteristics cc = null;
try {
cc = cm.getCameraCharacteristics(mCameraId);
} catch (CameraAccessException e) {
e.printStackTrace();
}
int myX = (int)event.getX();
int myY = (int)event.getY();
MeteringRectangle focusArea = new MeteringRectangle(myX-100,myY-100,200,200,MeteringRectangle.METERING_WEIGHT_DONT_CARE);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
try {
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
mBackgroundHandler);
// After this, the camera will go back to the normal state of preview.
mState = STATE_PREVIEW;
} catch (CameraAccessException e){
// log
}
if (isMeteringAreaAESupported(cc)) {
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, …Run Code Online (Sandbox Code Playgroud) 因此,我需要叠加camera2预览,并通过在顶部叠加透明叠加,在预览视频图像上绘制一个矩形。我从这里的基本Camera2代码开始:https://github.com/googlesamples/android-Camera2Basic
上面使用TextureView进行相机预览。
接下来,我将以下类添加到项目中
private class CustomView extends SurfaceView {
private final Paint paint;
private final SurfaceHolder mHolder;
private final Context context;
public CustomView(Camera2BasicFragment context) {
super(context.getActivity().getBaseContext());
mHolder = getHolder();
mHolder.setFormat(PixelFormat.TRANSPARENT);
this.context = context.getActivity().getBaseContext();
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
invalidate();
if (mHolder.getSurface().isValid()) {
final Canvas canvas = mHolder.lockCanvas();
Log.d("touch", "touchRecieved by camera");
if (canvas != null) { …Run Code Online (Sandbox Code Playgroud) 所以,我设法用我想要的方式用旧相机创建我想要的功能.
用mCamera.autoFocus(autoFocusCallback); 我检测到何时有焦点并在预览模式下运行所需的代码.
现在我很难掌握如何在camera2 API中做同样的事情.我的第一个想法是我会使用
private void process(CaptureResult result) {
switch (mState) {
case STATE_PREVIEW: {
// We have nothing to do when the camera preview is working normally.
int afState = result.get(CaptureResult.CONTROL_AF_STATE);
//if (CaptureResult.CONTROL_AF_STATE == afState) {
Log.d("SOME KIND OF FOCUS", "WE HAVE");
//}
break;
}
}
Run Code Online (Sandbox Code Playgroud)
但我没有找到某种状态告诉我,我们已经得到了关注.有人知道如何使用Camera2 API完成此操作吗?
我试图在Android设备上保存具有固定帧率(最好高达30)的图像序列,具有相同功能的camera2(Galaxy S7),但我无法a)获得稳定的帧率,b)达到甚至20fps(使用jpeg)编码).我已经包含了Android camera2捕获突发的建议太慢了.
根据,JPEG的最小帧持续时间是33.33毫秒(对于低于1920x1080的分辨率)
characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).getOutputMinFrameDuration(ImageFormat.JPEG, size);
Run Code Online (Sandbox Code Playgroud)
并且每个尺寸的稳定度为0ms(类似于YUV_420_888).
我的捕获构建器如下所示:
captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CONTROL_AE_MODE_OFF);
captureBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, _exp_time);
captureBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
captureBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, _iso_value);
captureBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, _foc_dist);
captureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CONTROL_AF_MODE_OFF);
captureBuilder.set(CaptureRequest.CONTROL_AWB_MODE, _wb_value);
// https://stackoverflow.com/questions/29265126/android-camera2-capture-burst-is-too-slow
captureBuilder.set(CaptureRequest.EDGE_MODE,CaptureRequest.EDGE_MODE_OFF);
captureBuilder.set(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE, CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE_OFF);
captureBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE, CaptureRequest.NOISE_REDUCTION_MODE_OFF);
captureBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
// Orientation
int rotation = getWindowManager().getDefaultDisplay().getRotation();
captureBuilder.set(CaptureRequest.JPEG_ORIENTATION,ORIENTATIONS.get(rotation));
Run Code Online (Sandbox Code Playgroud)
焦距设置为0.0(inf),iso设置为100,曝光时间设置为5ms.白平衡可以设置为OFF/AUTO/ANY VALUE,不会影响下面的时间.
我使用以下命令启动捕获会话:
session.setRepeatingRequest(_capReq.build(), captureListener, mBackgroundHandler);
Run Code Online (Sandbox Code Playgroud)
注意:如果我请求RepeatingRequest或RepeatingBurst,它没有区别.
在预览中(仅附加纹理表面),一切都是30fps.但是,只要我附加了一个图像阅读器(在HandlerThread上运行的监听器),我将其实例化如下(不保存,只测量帧之间的时间):
reader = ImageReader.newInstance(_img_width, _img_height, ImageFormat.JPEG, 2);
reader.setOnImageAvailableListener(readerListener, mBackgroundHandler);
Run Code Online (Sandbox Code Playgroud)
使用时间测量代码:
ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader myreader) {
Image image = null;
image = myreader.acquireNextImage();
if (image …Run Code Online (Sandbox Code Playgroud)