android 摄像头的调用
来源:互联网 发布:网络电视机顶盒哪个牌子好 编辑:程序博客网 时间:2024/05/22 00:48
记录一下自己写的camera2 Demo
布局文件:
TextureView 预览
ImageView 显示照片
Button 点击拍照
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextureView android:id="@+id/textureView" android:layout_width="match_parent" android:layout_height="match_parent" /> <ImageView android:id="@+id/iv_show_camera2_activity" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="visible" android:layout_centerInParent="true" android:scaleType="centerCrop" /> <Button android:id="@+id/take" android:layout_width="100dp" android:layout_height="50dp" android:text="拍照" android:layout_centerHorizontal="true" android:layout_alignParentBottom="true" android:layout_marginBottom="30dp"/></RelativeLayout>
MainActivity.class
import android.Manifest;import android.content.Context;import android.content.pm.PackageManager;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.ImageFormat;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.media.Image;import android.media.ImageReader;import android.os.Build;import android.os.Handler;import android.os.HandlerThread;import android.support.annotation.NonNull;import android.support.annotation.RequiresApi;import android.support.v4.app.ActivityCompat;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.util.SparseIntArray;import android.view.Surface;import android.view.TextureView;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.Toast;import java.nio.ByteBuffer;import java.util.Arrays;import java.util.concurrent.Semaphore;import java.util.concurrent.TimeUnit;@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)public class MainActivity extends AppCompatActivity { private final static String TAG = "tsb"; private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); //在关闭摄像机之前阻止应用程序退出的{链接信号量}。 private Semaphore mCameraOpenCloseLock = new Semaphore(1); ///为了使照片竖直显示 static { ORIENTATIONS.append(Surface.ROTATION_0, 90); ORIENTATIONS.append(Surface.ROTATION_90, 0); ORIENTATIONS.append(Surface.ROTATION_180, 270); ORIENTATIONS.append(Surface.ROTATION_270, 180); } //预览textureView private TextureView textureView; //摄像头管理器 private CameraManager mCameraManager; //摄像头id 通常0代表后置摄像头,1代表前置摄像头 private String mCameraID; //处理静态图像捕获 private ImageReader mImageReader; private CameraCaptureSession mCameraCaptureSession; private CameraDevice mCameraDevice; private CaptureRequest.Builder previewBuilder; private CaptureRequest.Builder pictureBuilder; private HandlerThread mHandlerThread; private Handler childHandler; private Button button; private ImageView imageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //查看是否拥有摄像头权限 没有就申请 if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED){ ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CAMERA},100); } button = (Button)findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { Toast.makeText(MainActivity.this,"没有照相机权限",Toast.LENGTH_LONG).show(); return; } if (button.getText().equals("拍照")) { takePicture(); button.setText("返回"); } else{ button.setText("拍照"); imageView.setVisibility(View.GONE); textureView.setVisibility(View.VISIBLE); } } }); imageView = (ImageView) findViewById(R.id.imageView); textureView = (TextureView) findViewById(R.id.textureView); textureView.setSurfaceTextureListener(surfaceTextureListener); } //TextureView 监听事件 TextureView.SurfaceTextureListener surfaceTextureListener = new TextureView.SurfaceTextureListener() { @Override public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { openCamera(); } @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 void openCamera() { if (mHandlerThread == null){ mHandlerThread = new HandlerThread("Camera2"); mHandlerThread.start(); childHandler = new Handler(mHandlerThread.getLooper()); } if (mImageReader == null){ mImageReader = ImageReader.newInstance(1080, 1920, ImageFormat.JPEG, 3); mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() { //可以在这里处理拍照得到的临时照片 例如,写入本地 @Override public void onImageAvailable(ImageReader reader) { // 拿到拍照照片数据 Image image = null; try{ image = reader.acquireLatestImage(); final Bitmap bitmap = imageToBitmap(image); if (bitmap != null) { runOnUiThread(new Runnable() { @Override public void run() { textureView.setVisibility(View.GONE); imageView.setVisibility(View.VISIBLE); imageView.setImageBitmap(bitmap); } }); } }catch (Exception e){ e.printStackTrace(); }finally { if (image!=null){ image.close(); image = null; } } } }, childHandler); } if (mCameraManager == null) mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); String cameraIds[] = {}; try { //获取所有摄像头ID cameraIds = mCameraManager.getCameraIdList(); } catch (CameraAccessException e) { Log.e(TAG, "Cam access exception getting IDs", e); } if (cameraIds.length < 1) { Log.e(TAG, "No cameras found"); return; } //通常0代表后置摄像头,1代表前置摄像头 mCameraID = cameraIds[0]; try { if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) { throw new RuntimeException("Time out waiting to lock camera opening."); } if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { Log.e(TAG,"没有照相机权限"); return; }else{ Log.e(TAG,"有照相机权限"); } //开启摄像头 mCameraManager.openCamera(mCameraID, stateCallback, null); } catch (CameraAccessException e) { e.printStackTrace(); } catch (InterruptedException e) { throw new RuntimeException("Interrupted while trying to lock camera opening.", e); } } //摄像头监听事件 private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() { @Override public void onOpened(@NonNull CameraDevice camera) { mCameraOpenCloseLock.release(); //打开摄像头 mCameraDevice = camera; takePreview(); } @Override public void onDisconnected(@NonNull CameraDevice camera) { mCameraOpenCloseLock.release(); //关闭摄像头 if (null != mCameraDevice) { mCameraDevice.close(); mImageReader.close(); mImageReader = null; } mCameraDevice = null; } @Override public void onError(@NonNull CameraDevice camera, int error) { mCameraOpenCloseLock.release(); mCameraDevice = null; //有错误 Log.e(TAG,"摄像头开启失败"); } }; /** * 预览 */ private void takePreview() { SurfaceTexture texture = textureView.getSurfaceTexture(); texture.setDefaultBufferSize(textureView.getWidth(), textureView.getHeight()); Surface surface = new Surface(texture); try { if (previewBuilder == null){ previewBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); previewBuilder.addTarget(surface); // 自动对焦 previewBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // 打开闪光灯 previewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); } mCameraDevice.createCaptureSession(Arrays.asList(surface,mImageReader.getSurface()), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(@NonNull CameraCaptureSession session) { if (mCameraDevice == null) return; mCameraCaptureSession = session; try { mCameraCaptureSession.setRepeatingRequest(previewBuilder.build(), null, childHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } @Override public void onConfigureFailed(@NonNull CameraCaptureSession session) { Log.e(TAG,"配置错误"); } }, null); } catch (CameraAccessException e) { e.printStackTrace(); } } /** * 拍照 */ private void takePicture(){ try { if (pictureBuilder == null){ pictureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); pictureBuilder.addTarget(mImageReader.getSurface()); // 自动对焦 pictureBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE); // 打开闪光灯 pictureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH); int rotation = getWindowManager().getDefaultDisplay().getRotation(); // 根据设备方向计算设置照片的方向 pictureBuilder.set(CaptureRequest.JPEG_ORIENTATION, ORIENTATIONS.get(rotation)); } mCameraCaptureSession.capture(pictureBuilder.build(), null, childHandler); } catch (CameraAccessException e) { e.printStackTrace(); } } /** * 关闭摄像头 */ private void closeCamera(){ try{ mCameraOpenCloseLock.acquire(); if (mCameraCaptureSession !=null){ mCameraCaptureSession.close(); mCameraCaptureSession = null; } if (mCameraDevice!= null){ mCameraDevice.close(); mCameraDevice = null; } if (mImageReader !=null){ mImageReader.close(); mImageReader = null; } stopBackgroundThread(); }catch (Exception e){ e.printStackTrace(); }finally { mCameraOpenCloseLock.release(); } } /** * 停止线程 */ private void stopBackgroundThread(){ if (mHandlerThread !=null){ mHandlerThread.quitSafely(); try { mHandlerThread.join(); mHandlerThread = null; childHandler = null; } catch (InterruptedException e) { e.printStackTrace(); } } } /** * image转bitmap * @param image * @return */ private Bitmap imageToBitmap(Image image){ ByteBuffer buffer = image.getPlanes()[0].getBuffer(); byte[] bytes = new byte[buffer.remaining()]; buffer.get(bytes);//由缓冲区存入字节数组 return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } @Override protected void onPause() { super.onPause(); closeCamera(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { if (permissions[0].equals(Manifest.permission.CAMERA) && grantResults[0] == PackageManager.PERMISSION_GRANTED) { closeCamera(); openCamera(); } }}
注意:
- TextureView初始化之后 执行 打开摄像头
mCameraManager.openCamera(mCameraID, stateCallback, null);
- 打开摄像头之后 执行 预览
private void takePreview(){...}
- 用文中拍照方法会出现卡顿
在textureView中已经预览,所以可以不用
mCameraCaptureSession.capture(pictureBuilder.build(), null, childHandler);
来拍照
可以直接用
textureView.getBitmap();
获取预览中的图片就OK了
CameraView
在网上有看到别人直接导入一个CameraView来实现预览以及拍照
首先导入
compile 'com.flurgle:camerakit:0.9.13'
在xml中调用
<com.flurgle.camerakit.CameraView android:id="@+id/cameraView" android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="center|top" />
在java文件中
CameraView cameraView = (CameraView) findViewById(R.id.cameraView);cameraView.setCameraListener(new CameraListener() { @Override public void onPictureTaken(byte[] picture) { super.onPictureTaken(picture); //拍到照片处理 Bitmap bitmap = BitmapFactory.decodeByteArray(picture, 0, picture.length) }});//换摄像头cameraView.toggleFacing();//拍照cameraView.captureImage();
阅读全文
0 0
- android 摄像头的调用
- android 摄像头的调用
- android前置摄像头的调用
- android-摄像头-调用前置摄像头
- Android摄像头和短信的调用
- android中调用系统封装的摄像头
- Android调用前置摄像头的方法
- Android 调用前置摄像头
- Android 调用系统摄像头
- android 调用摄像头
- Android 调用前置摄像头
- Android 调用前置摄像头
- Android程序调用摄像头
- Android如何调用摄像头
- Android 调用前置摄像头
- Android如何调用摄像头
- 1.Android调用摄像头
- android 调用摄像头拍照
- 栈
- linux中shell变量$#,$@,$0,$1,$2的含义解释
- 从mysql导出csv数据 并再将csv导入oracle
- python持久存储
- Java并发控制机制详解
- android 摄像头的调用
- Android面经-提升篇(持续更新...)
- iOS 一一 项目搭建与架构
- matlab publish
- bzoj 5088: HDU 6000 Wash
- 下拉列表select动态添加option和获取选中的option的值和value
- CentOS 6.5环境源码编译安装MySQL 5.6.34
- 解决 Android N 上 安装Apk时报错:android.os.FileUriExposedException: file:///storage/emulated/0/Download/appN
- android 纯代码 详细编写布局文件