android Camera2

 

控件:

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();
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI算法加油站

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值