Android 自定义相机Demo

本文是参考网上一些自定义相机示例,再结合自己对相机的功能需求写的,基本上包含了很多基本功能,比如相机对焦、闪光灯,以及在手机预览界面上绘制自己想要绘制的图案。

话不多说,先上一张图:
Android 自定义相机Demo 入门学习_第1张图片

应用是在Android Studio中开发的,java程序如下:

//主程序import android.annotation.SuppressLint;import android.content.Context;import android.content.Intent;import android.content.pm.PackageManager;import android.graphics.ImageFormat;import android.hardware.Camera;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.FrameLayout;import android.widget.ImageView;import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;@SuppressLint("NewApi")public class CameraActivity extends AppCompatActivity {    protected static final String TAG = "main";    private Camera mCamera;    private CameraPreview mPreview;    private static int Cur_State = 0;    public ImageView imgDu;    public File pictureFile;    Draw draw;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_camera);        imgDu = (ImageView) findViewById(R.id.img1);          mCamera = getCameraInstance();        draw = new Draw(CameraActivity.this);        // 创建预览类,并与Camera关联,最后添加到界面布局中        mPreview = new CameraPreview(this, mCamera);        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);        preview.addView(mPreview);        preview.addView(draw);        Button captureButton = (Button) findViewById(R.id.button_capture);  //button_capture        captureButton.setOnClickListener(new View.OnClickListener() {            @SuppressWarnings("deprecation")            @Override            public void onClick(View v) {                Camera.Parameters parameters = mCamera.getParameters();                // 设置相片格式                parameters.setJpegQuality(100);  //生成图像的质量                mCamera.setParameters(parameters);                parameters.setPictureFormat(ImageFormat.JPEG);                // 设置预览大小                parameters.setPreviewSize(800, 480);                parameters.setPictureSize(4160, 3120); //生成图像的风辨率                mCamera.setParameters(parameters);                parameters.setRotation(90);  //生成的图像旋转90度                mCamera.setParameters(parameters);                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);                mCamera.setParameters(parameters);                mCamera.autoFocus(new Camera.AutoFocusCallback() {                    @Override                    public void onAutoFocus(boolean success, Camera camera) {                        // 从Camera捕获图片                        mCamera.takePicture(null, null, mPicture);                    }                });                /*if (Cur_State < 2) {                    switch (Cur_State) {                        case 0:                            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);                            mCamera.setParameters(parameters);                            mCamera.autoFocus(new Camera.AutoFocusCallback() {                                @Override                                public void onAutoFocus(boolean success, Camera camera) {                                    // 从Camera捕获图片                                    mCamera.takePicture(null, null, mPicture);                                }                            });                            Cur_State++;                            break;                        case 1:                            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);//FLASH_MODE_OFF                            mCamera.setParameters(parameters);                            mCamera.autoFocus(new Camera.AutoFocusCallback() {                                @Override                                public void onAutoFocus(boolean success, Camera camera) {                                    // 从Camera捕获图片                                    mCamera.takePicture(null, null, mPicture);                                }                            });                            Cur_State++;                            break;                    }                } else {                    Cur_State = 0;                }*/        }        });    }    /** 检测设备是否存在Camera硬件 */    private boolean checkCameraHardware(Context context) {        if (context.getPackageManager().hasSystemFeature(                PackageManager.FEATURE_CAMERA)) {            // 存在            return true;        } else {            // 不存在            return false;        }    }    /** 打开一个Camera */    public static Camera getCameraInstance() {        Camera c = null;        try {            c = Camera.open();        } catch (Exception e) {            Log.d(TAG, "打开Camera失败失败");        }        return c;    }    private Camera.PictureCallback mPicture = new Camera.PictureCallback() {        @Override        public void onPictureTaken(byte[] data, Camera arg1) {            //将拍照得到的数据信息存储到本地            File tempFile=new File("/sdcard/temp.png");            try {                FileOutputStream fos=new FileOutputStream(tempFile);                fos.write(data);                fos.close();    //注意,,,然后将这个照片的数据信息传送给要进行展示的Activity即可,这部    //分代码是我自己需要的,你使用时需要将他去掉修改成你的。                Intent intent=new Intent(CameraActivity.this,MainActivity.class);                intent.putExtra("PicturePath", tempFile.getAbsolutePath());                startActivity(intent);                //拍照结束之后销毁当前的Activity,进入到图片展示界面                CameraActivity.this.finish();            } catch (FileNotFoundException e) {                // TODO Auto-generated catch block                e.printStackTrace();            } catch (IOException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }    };    @Override    protected void onDestroy() {        // 回收Camera资源        if(mCamera!=null){            mCamera.stopPreview();            mCamera.release();            mCamera=null;        }        super.onDestroy();    }}
/** * 定义一个预览类  预览界面设置 */import android.annotation.SuppressLint;import android.content.Context;import android.hardware.Camera;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceView;import java.io.IOException;@SuppressLint("NewApi")public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {    private static final String TAG = "main";    private SurfaceHolder mHolder;    @SuppressWarnings("deprecation")    private Camera mCamera;    @SuppressWarnings("deprecation")    public CameraPreview(Context context, Camera camera) {        super(context);        mCamera = camera;        // 通过SurfaceView获得SurfaceHolder        mHolder = getHolder();        // 为SurfaceHolder指定回调        mHolder.addCallback(this);        mCamera.setDisplayOrientation(90);    }    public void surfaceCreated(SurfaceHolder holder) {        // 当Surface被创建之后,开始Camera的预览        try {            mCamera.setPreviewDisplay(holder);            mCamera.startPreview();        } catch (IOException e) {            Log.d(TAG, "预览失败");        }    }    public void surfaceDestroyed(SurfaceHolder holder) {    }    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {        // Surface发生改变的时候将被调用,第一次显示到界面的时候也会被调用        if (mHolder.getSurface() == null){            // 如果Surface为空,不继续操作            return;        }        // 停止Camera的预览        try {            mCamera.stopPreview();        } catch (Exception e){            Log.d(TAG, "当Surface改变后,停止预览出错");        }        // 重新开始预览        try {            mCamera.setPreviewDisplay(mHolder);            mCamera.startPreview();        } catch (Exception e){            Log.d(TAG, "预览Camera出错");        }    }}
/** * Created by Administrator on 2018/1/24. * 这个是在预览界面绘制图案部分 */import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Path;import android.view.View;public class Draw extends View{    private Canvas canvas;//声明画笔    private Paint paint;//声明画布    private Paint paint1;    private Paint paint2;    private Bitmap bitmap;//声明位图    public Draw(Context context)    {        super(context);        // TODO 自动生成的构造函数存根        //创建一个画笔        paint = new Paint(Paint.DITHER_FLAG);        paint1 = new Paint(Paint.DITHER_FLAG);        paint2 = new Paint(Paint.DITHER_FLAG);        //设置位图的宽高,采用32位ARGB位图模式        bitmap = Bitmap.createBitmap(720, 1280, Bitmap.Config.ARGB_8888);        canvas = new Canvas(bitmap);        paint.setStyle(Paint.Style.STROKE);//设置非填充        paint.setStrokeWidth(2);//笔宽5像素        paint.setColor(Color.RED);//设置为红笔        paint.setAntiAlias(true);//锯齿不显示        paint.setDither(true);//设置图像抖动处理        paint.setStrokeJoin(Paint.Join.ROUND);//设置图像的结合方式        paint.setStrokeCap(Paint.Cap.ROUND);//设置画笔为圆形样式        paint1.setStyle(Paint.Style.FILL);//设置非填充        paint1.setStrokeWidth(33);//笔宽5像素        paint1.setStrokeJoin(Paint.Join.ROUND);//设置图像的结合方式        paint1.setStrokeCap(Paint.Cap.ROUND);//设置画笔为圆形样式        paint1.setColor(Color.BLACK);//设置为黑笔        paint.setAntiAlias(true);//锯齿不显示        paint.setDither(true);//设置图像抖动处理        paint2.setStyle(Paint.Style.FILL);//设置填充        paint2.setStrokeWidth(12);//笔宽5像素        paint2.setAntiAlias(true);//锯齿不显示        paint2.setDither(true);//设置图像抖动处理        paint2.setStrokeJoin(Paint.Join.ROUND);//设置图像的结合方式        paint2.setStrokeCap(Paint.Cap.ROUND);//设置画笔为圆形样式        paint2.setColor(Color.BLACK);//设置为黑笔    }    @SuppressLint("DrawAllocation")    @Override    protected void onDraw(Canvas canvas)    {        // TODO 自动生成的方法存根        super.onDraw(canvas);        canvas.drawBitmap(bitmap, 0, 0, paint);        float[] pts = {0,240,260,70};        canvas.drawLines(pts , paint);   //在画布上画线  1        float[] pts2 = {695,522,340,1040};        canvas.drawLines(pts2, paint);   //在画布上画线 2        Path mPath = new Path();        mPath.moveTo(260, 70);        mPath.quadTo(780, 0, 695, 522);        canvas.drawPath(mPath, paint);    //塞尔塔曲线        Path path = new Path();      //定义一条路径        path.moveTo(0,0);      //移动到 坐标(0,0)        path.lineTo(0,240);        path.lineTo(270,62);        path.lineTo(270,0);        path.lineTo(0,0);        canvas.drawPath(path, paint2);        Path path1 = new Path();      //定义一条路径        path1.moveTo(260,0);    //移动到 坐标(260,0)        path1.lineTo(720,0);        path1.lineTo(720,60);        path1.lineTo(260,60);        path1.lineTo(260,0);        canvas.drawPath(path1, paint2);        Path path2 = new Path();       //定义一条路径        path2.moveTo(720,60);    //移动到 坐标(720,60)        path2.lineTo(720,522);        path2.lineTo(715,522);        path2.lineTo(715,512);        path2.lineTo(700,60);        path2.lineTo(720,60);        canvas.drawPath(path2, paint2);        Path path3 = new Path();        //定义一条路径        path3.moveTo(340,1040);   //移动到 坐标(340,1040)        path3.lineTo(720,1040);        path3.lineTo(720,522);        path3.lineTo(710,512);        path3.lineTo(340,1040);        canvas.drawPath(path3, paint2);        Path path4 = new Path();        //定义一条路径        path4.moveTo(720,200);   //移动到 坐标(715,512)        path4.lineTo(500,60);        path4.lineTo(720,60);        path4.lineTo(720,200);        canvas.drawPath(path4, paint2);        float[] pts3 = {720,108,450,56};        canvas.drawLines(pts3, paint2);   //在画布上画线 3        float[] pts4 = {715,230,630,110};        canvas.drawLines(pts4, paint1);   //在画布上画线 4        float[] pts5 = {660,130,718,272};        canvas.drawLines(pts5, paint1);   //在画布上画线 5        float[] pts6 = {714,522,720,440};        canvas.drawLines(pts6, paint1);   //在画布上画线 6    }}

布局文件 activity_camera.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    >    <FrameLayout        android:id="@+id/camera_preview"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_weight="1"        />    <Button        android:id="@+id/button_capture"        android:text="拍照"        android:textColor="#6633cc"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_gravity="bottom"        />LinearLayout>

应用权限:

    <uses-permission android:name="android.permission.CAMERA"/> >    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />    <uses-permission android:name="android.permission.RECORD_AUDIO" />    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

具体的细节就不在说明,可以自己在网上搜一下相关知识,大家使用中有什么问题可以留言哦,如果能解决尽量帮大家解决。

更多相关文章

  1. 基于Android的图像处理演示软件介绍文档
  2. Android 图像按钮ImageButton
  3. Gallery图像重叠问题以及每屏只显示一张
  4. 实现android图像识别的几种方法
  5. Android下使用camera2和Surfaceview预览图像并取得YUV420p数据回
  6. Android和C#基于UDP的实时图像传输

随机推荐

  1. MySQL巧用sum、case和when优化统计查询
  2. MySQL中sum函数使用的实例教程
  3. 浅谈为什么MySQL不推荐使用子查询和join
  4. MySQL中 and or 查询的优先级分析
  5. MySQL中查看数据库安装路径的方法
  6. 细说mysql replace into用法
  7. mysql触发器trigger实例详解
  8. MySQL8.0.23免安装版配置详细教程
  9. mysql8.0.23 msi安装超详细教程
  10. MySQL中触发器和游标的介绍与使用