android获取摄像头视频帧数据
16lz
2021-01-23
1.思路
一.通过android的Camera.setPreviewCallback(PreviewCallback cb)监听回调.
二.此回调函数public void onPreviewFrame(byte[] data, Camera camera)每回调一次就是获取到摄像头的一帧原始数据即data字节数组。
三.这个字节数组经过YuvImage类包装压缩成特定类型图片。
2.代码实现
一.权限
二.布局
<?xml version="1.0" encoding="utf-8"?>
三.java实现代码
package com.yuncai.menjin.camera_demo;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.ImageFormat;import android.graphics.Rect;import android.graphics.SurfaceTexture;import android.graphics.YuvImage;import android.hardware.Camera;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.TextureView;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.Toast;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.util.List;public class MainActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener { private TextureView textureView; private ImageView ivPic; private Button btnTakePic; private Camera mCamera; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); initData(); initListener(); } private void initListener() { textureView.setSurfaceTextureListener(this); btnTakePic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { addCallBack(); } }); } private void initData() { int numberOfCameras = Camera.getNumberOfCameras();// 获取摄像头个数 if(numberOfCameras<1){ Toast.makeText(this, "没有相机", Toast.LENGTH_SHORT).show(); finish(); return; } } private void initView() { textureView = (TextureView) findViewById(R.id.texture_view);// textureView.setRotation(0); // // 设置预览角度,并不改变获取到的原始数据方向(与Camera.setDisplayOrientation(0)相同) ivPic = (ImageView) findViewById(R.id.iv_pic); btnTakePic = (Button) findViewById(R.id.btn_takePic); } @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { // 打开相机 0后置 1前置 mCamera = Camera.open(0); if (mCamera != null) { // 设置相机预览宽高,此处设置为TextureView宽高 Camera.Parameters params = mCamera.getParameters(); params.setPreviewSize(width, height); // 设置自动对焦模式 List focusModes = params.getSupportedFocusModes(); if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) { params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); mCamera.setParameters(params); } try {// mCamera.setDisplayOrientation(0);// 设置预览角度,并不改变获取到的原始数据方向 // 绑定相机和预览的View mCamera.setPreviewTexture(surface); // 开始预览 mCamera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } } private void addCallBack() { if(mCamera!=null){ mCamera.setPreviewCallback(new Camera.PreviewCallback() { @Override public void onPreviewFrame(byte[] data, Camera camera) { Camera.Size size = camera.getParameters().getPreviewSize(); try{ YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null); if(image!=null){ ByteArrayOutputStream stream = new ByteArrayOutputStream(); image.compressToJpeg(new Rect(0, 0, size.width, size.height), 80, stream); Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size()); ivPic.setImageBitmap(bmp); stream.close(); } }catch(Exception e){ e.printStackTrace(); } } }); } } @Override public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {} @Override public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { mCamera.stopPreview(); mCamera.release(); return false; } @Override public void onSurfaceTextureUpdated(SurfaceTexture surface) {}}
3.效果
更多相关文章
- 极客学院Android视频分享
- [Android Training视频系列] 8.2 Managing Audio Focus
- Android 实时视频编码—H.264硬编码
- android获取手机上的图片和视频缩略图thumbnails
- Android Camera系列开发 (二)通过Intent录制视频
- Android开发所有视频教程汇总
- Android 获取摄像头像素,个数