android 自定义相机Camera
项目中,有时系统的相机不能满足我们的需求,例如:实现美图,这样就需要我们进行自定义相机,满足我们的特殊需求。Android给我们提供了Camera API,可以进行相机的私人订制。在Android5以后有提供了Camera2 API,废除了Camera API。但Camera仍旧可以使用,Camera2使用起来感觉比Camera要复杂些,Camera2功能要强于Camera,也是google提倡使用的。Camera已经基本可以满足需求了,今天我们就要看一下Camera的使用,下一篇我们会讲到Camera2的使用。
一、获取Camera
camera=Camera.open();二、与SurfaceView进行关联(SurfaceView进行图像绘制)
sfh=sfv.getHolder(); sfh.addCallback(new SurfaceHolder.Callback() { //创建 @Override public void surfaceCreated(SurfaceHolder holder) { //开始进行图片的预览 startPreview(); } //改变 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { //停止旧的预览,开启新的预览 camera.stopPreview(); startPreview(); } //释放 @Override public void surfaceDestroyed(SurfaceHolder holder) { //停止预览,释放资源 stopCamera(); } });三、进行预览
/** * 相机预览*/ private void startPreview(){ try { //相机与SurfaceView进行绑定 camera.setPreviewDisplay(sfh); //预览的图片旋转 camera.setDisplayOrientation(90); camera.startPreview(); } catch (IOException e) { e.printStackTrace(); } }
四、拍照
btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //设置相机的各种参数 Camera.Parameters parameters=camera.getParameters(); //对焦的方式 parameters.setFocusMode(Camera.Parameters.ANTIBANDING_AUTO); //照片的类型 parameters.setPictureFormat(ImageFormat.JPEG); //对焦监听 camera.autoFocus(new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { //对焦成功 if(success){ camera.takePicture(null,null,cameraCallBack); }else{ Toast.makeText(MainActivity.this,"对焦失败!",Toast.LENGTH_SHORT).show(); } } }); } });五、处理拍照图片,进行存到本地相册,和本页面预览
/** * 拍照成功回调函数*/ private Camera.PictureCallback cameraCallBack=new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { startPreview(); //先验证手机是否有sdcard String status= Environment.getExternalStorageState(); if(!status.equals(Environment.MEDIA_MOUNTED)) { Toast.makeText(getApplicationContext(),"你的sd卡不可用。",Toast.LENGTH_SHORT).show(); return; } //大部分手机拍照都是存到这个路径 String filePath=Environment.getExternalStorageDirectory().getPath()+"/DCIM/Camera/"; String picturePath=System.currentTimeMillis()+".jpg"; File file=new File(filePath,picturePath); try{ //存到本地相册 FileOutputStream fileOutputStream=new FileOutputStream(file); fileOutputStream.write(data); fileOutputStream.close(); //显示图片 BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options); iv.setImageBitmap(bitmap); }catch (FileNotFoundException e){ e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } } };
六、资源的释放
/** * 停止拍照释放资源*/ private void stopCamera(){ if(camera!=null){ camera.stopPreview(); camera.release(); camera=null; } }
放上activity代码:
package com.sunshanglei.camera.customcamera; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.ImageFormat; import android.hardware.Camera; import android.os.Environment; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; /** * use 自定义相机Camera * author 孙尚磊 * create time 2017-4-26 */ public class MainActivity extends AppCompatActivity { private SurfaceView sfv; private ImageView iv; private Button btn; private Camera camera=null; private SurfaceHolder sfh; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sfv= (SurfaceView) findViewById(R.id.sfv); iv= (ImageView) findViewById(R.id.iv); btn= (Button) findViewById(R.id.btn); camera=Camera.open(); sfh=sfv.getHolder(); sfh.addCallback(new SurfaceHolder.Callback() { //创建 @Override public void surfaceCreated(SurfaceHolder holder) { //开始进行图片的预览 startPreview(); } //改变 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { //停止旧的预览,开启新的预览 camera.stopPreview(); startPreview(); } //释放 @Override public void surfaceDestroyed(SurfaceHolder holder) { //停止预览,释放资源 stopCamera(); } }); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //设置相机的各种参数 Camera.Parameters parameters=camera.getParameters(); //对焦的方式 parameters.setFocusMode(Camera.Parameters.ANTIBANDING_AUTO); //照片的类型 parameters.setPictureFormat(ImageFormat.JPEG); //对焦监听 camera.autoFocus(new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { //对焦成功 if(success){ camera.takePicture(null,null,cameraCallBack); }else{ Toast.makeText(MainActivity.this,"对焦失败!",Toast.LENGTH_SHORT).show(); } } }); } }); } /** * 拍照成功回调函数*/ private Camera.PictureCallback cameraCallBack=new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { startPreview(); //先验证手机是否有sdcard String status= Environment.getExternalStorageState(); if(!status.equals(Environment.MEDIA_MOUNTED)) { Toast.makeText(getApplicationContext(),"你的sd卡不可用。",Toast.LENGTH_SHORT).show(); return; } //大部分手机拍照都是存到这个路径 String filePath=Environment.getExternalStorageDirectory().getPath()+"/DCIM/Camera/"; String picturePath=System.currentTimeMillis()+".jpg"; File file=new File(filePath,picturePath); try{ //存到本地相册 FileOutputStream fileOutputStream=new FileOutputStream(file); fileOutputStream.write(data); fileOutputStream.close(); //显示图片 BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 2; Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options); iv.setImageBitmap(bitmap); }catch (FileNotFoundException e){ e.printStackTrace(); }catch (IOException e){ e.printStackTrace(); } } }; @Override protected void onResume() { super.onResume(); if(camera==null){ camera=Camera.open(); if(sfh!=null){ startPreview(); } } } @Override protected void onPause() { super.onPause(); if(camera!=null) { stopCamera(); } } /** * 相机预览*/ private void startPreview(){ try { //相机与SurfaceView进行绑定 camera.setPreviewDisplay(sfh); //预览的图片旋转 camera.setDisplayOrientation(90); camera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } /** * 停止拍照释放资源*/ private void stopCamera(){ if(camera!=null){ camera.stopPreview(); camera.release(); camera=null; } } }
布局xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <SurfaceView android:id="@+id/sfv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@+id/ll_bottom"/> <RelativeLayout android:id="@+id/ll_bottom" android:layout_width="match_parent" android:layout_height="80dp" android:layout_alignParentBottom="true"> <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="70dp" android:layout_centerVertical="true" android:layout_marginLeft="10dp" android:src="@mipmap/ic_launcher"/> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_centerVertical="true" android:layout_marginRight="10dp" android:text="拍照"/> </RelativeLayout> </RelativeLayout>
最后不要忘了放上权限:
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
效果图:
apk下载:http://download.****.net/detail/qq_38416326/9827219
源码下载:http://download.****.net/detail/qq_38416326/9827225
https://github.com/sunshanglei/CustomCamera
转载https://blog.****.net/qq_38416326/article/details/70809754