android Camera2
【摘要】
控件:
import android.view.TextureView;
这个是代码:
https://github.com/plumcot/Camera2Demo/blob/master/src/com/example/camera2demo/Camera2Demo.java
获取图片数据不对,应该是:
privat...
控件:
import android.view.TextureView;
这个是代码:
https://github.com/plumcot/Camera2Demo/blob/master/src/com/example/camera2demo/Camera2Demo.java
获取图片数据不对,应该是:
-
private void setupImageReader() {
-
//前三个参数分别是需要的尺寸和格式,最后一个参数代表每次最多获取几帧数据,本例的2代表ImageReader中最多可以获取两帧图像流
-
mImageReader = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(),
-
ImageFormat.JPEG, 2);
-
//监听ImageReader的事件,当有图像流数据可用时会回调onImageAvailable方法,它的参数就是预览帧数据,可以对这帧数据进行处理
-
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
-
@Override
-
public void onImageAvailable(ImageReader reader) {
-
Image image = reader.acquireLatestImage();
-
//我们可以将这帧数据转成字节数组,类似于Camera1的PreviewCallback回调的预览帧数据
-
ByteBuffer buffer = image.getPlanes()[0].getBuffer();
-
byte[] data = new byte[buffer.remaining()];
-
buffer.get(data);
-
image.close();
-
}
-
}, null);
-
}
-
package com.mtcnn_as;
-
-
import java.nio.ByteBuffer;
-
import java.util.Arrays;
-
-
import android.Manifest;
-
import android.app.Activity;
-
import android.content.Context;
-
import android.content.pm.PackageManager;
-
import android.graphics.Bitmap;
-
import android.graphics.BitmapFactory;
-
import android.graphics.ImageFormat;
-
import android.graphics.Matrix;
-
import android.graphics.SurfaceTexture;
-
import android.hardware.camera2.CameraAccessException;
-
import android.hardware.camera2.CameraCaptureSession;
-
import android.hardware.camera2.CameraCharacteristics;
-
import android.hardware.camera2.CameraDevice;
-
import android.hardware.camera2.CameraManager;
-
import android.hardware.camera2.CaptureRequest;
-
import android.hardware.camera2.params.StreamConfigurationMap;
-
import android.media.Image;
-
import android.media.ImageReader;
-
import android.os.Bundle;
-
import android.os.Handler;
-
import android.os.HandlerThread;
-
import android.support.v4.app.ActivityCompat;
-
import android.support.v4.content.ContextCompat;
-
import android.util.Log;
-
import android.util.Size;
-
import android.view.Surface;
-
import android.view.TextureView;
-
import static com.mtcnn_as.ImageUtils.saveBitmap;
-
public class Camera2Demo extends Activity implements
-
TextureView.SurfaceTextureListener {
-
-
private CameraDevice mCamera;
-
private String mCameraID = "1";
-
-
private TextureView mPreviewView;
-
private Size mPreviewSize;
-
private CaptureRequest.Builder mPreviewBuilder;
-
private ImageReader mImageReader;
-
-
private Handler mHandler;
-
private HandlerThread mThreadHandler;
-
-
// 这里定义的是ImageReader回调的图片的大小
-
private int mImageWidth = 1920;
-
private int mImageHeight = 1080;
-
-
@Override
-
public void onCreate(Bundle savedInstanceState) {
-
super.onCreate(savedInstanceState);
-
setContentView(R.layout.activity_texture);
-
-
initView();
-
initLooper();
-
-
}
-
-
// 很多过程都变成了异步的了,所以这里需要一个子线程的looper
-
private void initLooper() {
-
mThreadHandler = new HandlerThread("CAMERA2");
-
mThreadHandler.start();
-
mHandler = new Handler(mThreadHandler.getLooper());
-
}
-
-
// 可以通过TextureView或者SurfaceView
-
private void initView() {
-
mPreviewView = (TextureView) findViewById(R.id.textureView);
-
mPreviewView.setSurfaceTextureListener(this);
-
}
-
-
@Override
-
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
-
int height) {
-
try {
-
// 获得所有摄像头的管理者CameraManager
-
CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
-
// 获得某个摄像头的特征,支持的参数
-
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(mCameraID);
-
// 支持的STREAM CONFIGURATION
-
StreamConfigurationMap map = characteristics
-
.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-
// 摄像头支持的预览Size数组
-
mPreviewSize = map.getOutputSizes(SurfaceTexture.class)[0];
-
-
if (ContextCompat.checkSelfPermission(Camera2Demo.this,
-
Manifest.permission.CAMERA)
-
!= PackageManager.PERMISSION_GRANTED ||
-
ContextCompat.checkSelfPermission(Camera2Demo.this,
-
Manifest.permission.WRITE_EXTERNAL_STORAGE)
-
!= PackageManager.PERMISSION_GRANTED) {
-
-
ActivityCompat.requestPermissions(Camera2Demo.this,
-
new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
-
}
-
// 打开相机
-
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
-
// TODO: Consider calling
-
// ActivityCompat#requestPermissions
-
// here to request the missing permissions, and then overriding
-
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
-
// int[] grantResults)
-
// to handle the case where the user grants the permission. See the documentation
-
// for ActivityCompat#requestPermissions for more details.
-
return;
-
}
-
cameraManager.openCamera(mCameraID, mCameraDeviceStateCallback, mHandler);
-
} catch (CameraAccessException e) {
-
e.printStackTrace();
-
}
-
}
-
-
@Override
-
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
-
int height) {
-
-
}
-
-
@Override
-
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
-
return false;
-
}
-
-
// 这个方法要注意一下,因为每有一帧画面,都会回调一次此方法
-
@Override
-
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
-
-
}
-
-
private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
-
-
@Override
-
public void onOpened(CameraDevice camera) {
-
try {
-
mCamera = camera;
-
startPreview(mCamera);
-
} catch (CameraAccessException e) {
-
e.printStackTrace();
-
}
-
}
-
-
@Override
-
public void onDisconnected(CameraDevice camera) {
-
-
}
-
-
@Override
-
public void onError(CameraDevice camera, int error) {
-
-
}
-
};
-
-
// 开始预览,主要是camera.createCaptureSession这段代码很重要,创建会话
-
private void startPreview(CameraDevice camera) throws CameraAccessException {
-
SurfaceTexture texture = mPreviewView.getSurfaceTexture();
-
-
// 这里设置的就是预览大小
-
texture.setDefaultBufferSize(mPreviewSize.getWidth(),mPreviewSize.getHeight());
-
Surface surface = new Surface(texture);
-
try {
-
// 设置捕获请求为预览,这里还有拍照啊,录像等
-
mPreviewBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-
} catch (CameraAccessException e) {
-
e.printStackTrace();
-
}
-
-
// 就是在这里,通过这个set(key,value)方法,设置曝光啊,自动聚焦等参数!! 如下举例:
-
// mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE,CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
-
-
mImageReader = ImageReader.newInstance(mImageWidth, mImageHeight,
-
ImageFormat.JPEG/* 此处还有很多格式,比如我所用到YUV等 */, 2/*
-
* 最大的图片数,
-
* mImageReader里能获取到图片数
-
* ,
-
* 但是实际中是2+1张图片,就是多一张
-
*/);
-
-
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener,mHandler);
-
// 这里一定分别add两个surface,一个Textureview的,一个ImageReader的,如果没add,会造成没摄像头预览,或者没有ImageReader的那个回调!!
-
mPreviewBuilder.addTarget(surface);
-
mPreviewBuilder.addTarget(mImageReader.getSurface());
-
camera.createCaptureSession(
-
Arrays.asList(surface, mImageReader.getSurface()),
-
mSessionStateCallback, mHandler);
-
}
-
-
private CameraCaptureSession.StateCallback mSessionStateCallback = new CameraCaptureSession.StateCallback() {
-
-
@Override
-
public void onConfigured(CameraCaptureSession session) {
-
try {
-
updatePreview(session);
-
} catch (CameraAccessException e) {
-
e.printStackTrace();
-
}
-
}
-
-
@Override
-
public void onConfigureFailed(CameraCaptureSession session) {
-
-
}
-
};
-
-
private void updatePreview(CameraCaptureSession session)
-
throws CameraAccessException {
-
session.setRepeatingRequest(mPreviewBuilder.build(), null, mHandler);
-
}
-
-
private ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
-
-
/**
-
* 当有一张图片可用时会回调此方法,但有一点一定要注意: 一定要调用
-
* reader.acquireNextImage()和close()方法,否则画面就会卡住!!!!!我被这个坑坑了好久!!!
-
* 很多人可能写Demo就在这里打一个Log,结果卡住了,或者方法不能一直被回调。
-
**/
-
@Override
-
public void onImageAvailable(ImageReader reader) {
-
-
long startTime = System.currentTimeMillis(); //起始时间
-
Image img = reader.acquireNextImage();
-
/**
-
* 因为Camera2并没有Camera1的Priview回调!!!所以该怎么能到预览图像的byte[]呢?就是在这里了!!!
-
* 我找了好久的办法!!!
-
**/
-
ByteBuffer buffer = img.getPlanes()[0].getBuffer();
-
// 这里就是图片的byte数组了
-
byte[] bytes = new byte[buffer.remaining()];
-
buffer.get(bytes);
-
img.close();
-
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
-
Matrix matrix = new Matrix();
-
matrix.postRotate(270);
-
// matrix.postScale( 1/2, 1/2); // 长和宽放大缩小的比例
-
Bitmap bimap1 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
-
-
int faceInfo[] = null;
-
-
Bitmap rgba = bimap1.copy(Bitmap.Config.ARGB_8888, true);
-
-
long endTime = System.currentTimeMillis(); //结束时间
-
-
int width = rgba.getWidth();
-
int height = rgba.getHeight();
-
byte[] imageDate = getPixelsRGBA(rgba);
-
long endTime2 = System.currentTimeMillis(); //结束时间
-
saveBitmap(getApplicationContext(),rgba);
-
-
Log.e("test", String.format("方法使用时间 %d %d ms", endTime - startTime,endTime2-startTime));
-
-
-
}
-
};
-
-
//提取像素点
-
private byte[] getPixelsRGBA(Bitmap image) {
-
// calculate how many bytes our image consists of
-
int bytes = image.getByteCount();
-
ByteBuffer buffer = ByteBuffer.allocate(bytes); // Create a new buffer
-
image.copyPixelsToBuffer(buffer); // Move the byte data to the buffer
-
byte[] temp = buffer.array(); // Get the underlying array containing the
-
-
return temp;
-
}
-
protected void onPause() {
-
if (null != mCamera) {
-
mCamera.close();
-
mCamera = null;
-
}
-
if (null != mImageReader) {
-
mImageReader.close();
-
mImageReader = null;
-
}
-
super.onPause();
-
}
-
}
文章来源: blog.csdn.net,作者:网奇,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/jacke121/article/details/101514590
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)