内容简介:限于硬件成本,有时需要使用Android原生的camera无预览采集YUV数据,用于生成图片与h.264编码。要实现该功能,只需要调用setPreviewTexture即可。
限于硬件成本,有时需要使用Android原生的camera无预览采集YUV数据,用于生成图片与h.264编码。要实现该功能,只需要调用setPreviewTexture即可。
1、相机CameraHelper
public class CameraHelper implements Camera.PreviewCallback { private static final String TAG = "CameraHelper"; public static final int WIDTH = 640; public static final int HEIGHT = 480; private int mCameraId; private Camera mCamera; private byte[] buffer; private SurfaceTexture surfaceTexture = new SurfaceTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); private boolean shut = false; private OnPictureRawCapture pictureRawCaptureListener; public void setPictureRawCaptureListener(OnPictureRawCapture pictureRawCaptureListener) { this.pictureRawCaptureListener = pictureRawCaptureListener; } public CameraHelper(int cameraId){ mCameraId = cameraId; } public void switchCamera(){ if (mCameraId == Camera.CameraInfo.CAMERA_FACING_BACK){ mCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT; }else{ mCameraId = Camera.CameraInfo.CAMERA_FACING_BACK; } stopPreview(); startPreview(); } public void startPreview() { try { mCamera = Camera.open(mCameraId); Camera.Parameters parameters = mCamera.getParameters(); parameters.setPreviewFormat(ImageFormat.NV21); parameters.setPreviewSize(WIDTH, HEIGHT); mCamera.setParameters(parameters); buffer = new byte[WIDTH * HEIGHT *3/2]; mCamera.addCallbackBuffer(buffer); mCamera.setPreviewCallbackWithBuffer(this); mCamera.setPreviewTexture(surfaceTexture);// mCamera.startPreview(); } catch (IOException e) { Log.e(TAG, "start preview failed"); e.printStackTrace(); } } public void stopPreview() { if (mCamera == null){ mCamera.setPreviewCallback(null); mCamera.stopPreview(); mCamera.release(); mCamera = null; } } @Override public void onPreviewFrame(byte[] data, Camera camera) { if(shut){ shut = false; if(pictureRawCaptureListener != null){ pictureRawCaptureListener.onCapture(data);//生成图片 } } //to do //h.264编码、模式识别等 camera.addCallbackBuffer(buffer); } public void takePicture(){//拍照 shut = true; } public interface OnPictureRawCapture{ void onCapture(byte[] data); } public Camera.Size getPreviewSize(){ Camera.Size previewSize = mCamera.getParameters().getPreviewSize(); return previewSize; } } 复制代码
2、相机启动线程
public class CameraRunnable implements Runnable{ private CameraHelper cameraHelper; public CameraRunnable(CameraHelper cameraHelper) { this.cameraHelper = cameraHelper; } @Override public void run() { cameraHelper.startPreview(); } } 复制代码
3、生成图片文件线程
public class PictureRunnable implements Runnable{ private static final String CAPTRUE_PATH = "sdcard/img/"; private static final String TEMPLATE = "yyyy_MM_dd_HH_mm_ss"; private SimpleDateFormat sdf = new SimpleDateFormat("", Locale.SIMPLIFIED_CHINESE); private Camera.Size previewSize; private byte[] imgRaw; public PictureRunnable(byte[] data,Camera.Size size){ this.imgRaw = data; this.previewSize = size; } @Override public void run() { createBmpAndSaveFile(imgRaw); } private void createBmpAndSaveFile(byte[] data) { BitmapFactory.Options newOpts = new BitmapFactory.Options(); newOpts.inJustDecodeBounds = true; YuvImage yuvimage = new YuvImage( data, ImageFormat.NV21, previewSize.width, previewSize.height, null); ByteArrayOutputStream baos = new ByteArrayOutputStream(); yuvimage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 100, baos); byte[] rawImage = baos.toByteArray(); Bitmap bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length); try { baos.close(); } catch (IOException e) { e.printStackTrace(); } ![](https://user-gold-cdn.xitu.io/2019/7/1/16baca01448739cb?w=559&h=276&f=png&s=193437) if (bitmap == null) return; else { try { saveFile(bitmap); } catch (IOException e) { e.printStackTrace(); } } } private void saveFile(Bitmap bm) throws IOException { String fileName = getFileName()+".jpeg"; File dirFile = new File(CAPTRUE_PATH); if(!dirFile.exists()){ dirFile.mkdir(); } File myCaptureFile = new File(CAPTRUE_PATH + fileName); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile)); bm.compress(Bitmap.CompressFormat.JPEG, 80, bos); bos.flush(); bos.close(); bm.recycle(); bm=null; Log.d("CameraHelper","new img:"+myCaptureFile.getAbsolutePath()); EventBus.getDefault().post(myCaptureFile.getAbsolutePath()); } private String getFileName() { long time = System.currentTimeMillis(); sdf.applyPattern(TEMPLATE); return sdf.format(time); } } 复制代码
4、程序入口
4.1 开启相机
private CameraHelper myCamera; private ExecutorService executorService; private CameraRunnable cameraRunnable; executorService = new ThreadPoolExecutor(2,4,0, TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>(10)); myCamera = new CameraHelper( Camera.CameraInfo.CAMERA_FACING_BACK); myCamera.setPictureRawCaptureListener(this); cameraRunnable = new CameraRunnable(myCamera); executorService.execute(cameraRunnable); 复制代码
4.2 拍照
myCamera.takePicture(); 复制代码
4.2.1 保存图片
@Override public void onCapture(byte[] data) { Log.d("CameraHelper","onCapture "+data.length); Camera.Size previewSize = myCamera.getPreviewSize(); executorService.execute(new PictureRunnable(data,previewSize)); } 复制代码
4.3 关闭相机
executorService.shutdownNow(); myCamera.stopPreview(); 复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
JS 压缩/解压工具
在线压缩/解压 JS 代码
RGB转16进制工具
RGB HEX 互转工具