android 自定义Camera控件

简单实现Camera自定义控件:

效果图:




具体代码解释在代码中有记录,主要代码如下:

先看下布局文件:

activity_camera.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".MainActivity">


    <com.example.vic.myapplication.CustomCamera
        android:id="@+id/camera"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <ImageView
        android:layout_marginBottom="8dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/iv_takephoto"
        android:onClick="takePhoto"
         />
</RelativeLayout>


CameraActivity.java

package com.example.vic.myapplication;

import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;

import com.example.vic.myapplication.base.BaseActivity;

/**
 * Created by Administrator on 2016/1/14.
 */
public class CameraActivity extends BaseActivity {
    private CustomCamera customCamera;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setToolBarInfo(true);
        getToolBar_center().setText("Camera");
        setContentLayout(R.layout.activity_camera);

        customCamera = (CustomCamera) findViewById(R.id.camera);

    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            customCamera.autoFocus(false);
            return true;
        }
        return super.onTouchEvent(event);
    }

    public void takePhoto(View v) {
        customCamera.autoFocus(true);
    }

}

下面的CustomCamera.java

package com.example.vic.myapplication;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.os.Environment;
import android.text.format.Time;
import android.util.AttributeSet;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.example.vic.myapplication.utils.AppLog;
import com.example.vic.myapplication.utils.AppToast;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * Created by Administrator on 2016/1/14.
 */
public class CustomCamera extends SurfaceView implements SurfaceHolder.Callback {

    private Camera camera;
    private SurfaceHolder holder;
    private Context context;
    private String picUrl;


    public CustomCamera(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        initHolder();
    }

    private void initHolder() {
        //实例holder
        holder = this.getHolder();
        //设置屏常 亮
        holder.setKeepScreenOn(true);
        //增加一个回调
        holder.addCallback(this);
    }

    /**
     * 判断是否存在摄像头
     * @param context
     * @return
     */
    private boolean existCamera(Context context) {
        return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
    }

    /**
     * 初始化相机
     * 0    表示后置camera
     * Camera.getNumberOfCameras()-1  可调用前置camera
     */
    private void initCamera() {
        if (camera == null) {
//            camera = Camera.open(Camera.getNumberOfCameras() - 1);//前置摄像头
            camera = Camera.open();
        }
    }


    private void imagePreview(SurfaceHolder holder) {
        try {
            if (camera != null) {
                //设置预览显示到holder
                camera.setPreviewDisplay(holder);
                //系统默认是横向的, 所以要设置方向为顺时针90度
                camera.setDisplayOrientation(90);
                //开始预览
                camera.startPreview();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void setParameters() {
        if (camera != null) {
            //获取相机的参数设置对象
            Camera.Parameters parameters = camera.getParameters();
            //设置图片格式
            parameters.setPictureFormat(ImageFormat.JPEG);
            //设置自动闪光灯
            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
            //对parametrs对象进行修改后,重新赋值
            camera.setParameters(parameters);
        }
    }

    private void releaseCamera() {
        if (camera != null) {
            //取消预览回调
            camera.setPreviewCallback(null);
            //停止预览
            camera.stopPreview();
            //释放camera
            camera.release();
            //置空
            camera = null;
        }
    }

    /**
     * 自动聚焦
     * @param b  ture为自动聚焦后,就拍照, false为只自动聚焦
     */
    public void autoFocus(final boolean b) {
        if (camera != null) {
            camera.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {
                    if (success) {
                        if (b)
                        takePicture();
                    }

                }
            });
        }
    }


    public void takePicture() {
        if (camera != null) {
            camera.takePicture(null, null, new Camera.PictureCallback() {
                @Override
                public void onPictureTaken(byte[] data, Camera camera) {

                    // data就是图片信息
                    //声明bitmap对象
                    Bitmap bMap;
                    try {
                        //将数据读到bitmap
                        bMap = BitmapFactory.decodeByteArray(data, 0, data.length);
                        //系统默认返回图片是横向的,下面操作对照片就行旋转90度
                        Bitmap bMap2;
                        Matrix matrix = new Matrix();
                        matrix.reset();
                        matrix.setRotate(90);
                        bMap2 = Bitmap.createBitmap(bMap, 0, 0, bMap.getWidth(),
                                bMap.getHeight(), matrix, true);
                        bMap = bMap2;
                        //照片保存

                        if (picUrl == null) {
                            picUrl = Environment.getExternalStorageDirectory() + File.separator +pictureName()+".jpg";
                        }
                        File file = new File(picUrl);
                        if (file.exists()) {
                            file.delete();
                        }
                        BufferedOutputStream bos =
                                new BufferedOutputStream(new FileOutputStream(file));
                        bMap.compress(Bitmap.CompressFormat.JPEG, 100, bos);//将图片压缩到流中
                        bos.flush();//输出
                        bos.close();//关闭


                        bMap.recycle();
                        bMap2.recycle();
                        //保存后,重新预览
                        imagePreview(holder);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (existCamera(context)) {
            initCamera();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        AppLog.Log("surfaceChanged()");
        setParameters();
        imagePreview(holder);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        AppLog.Log("surfaceDestroyed()");
        releaseCamera();
    }

    public void setPicUrl(String picUrl) {
        this.picUrl = picUrl;
        AppLog.Log("setPicUrl()");
    }

    public String pictureName() {
        String str = "";
        Time t = new Time();
        t.setToNow(); // 取得系统时间。
        int year = t.year;
        int month = t.month + 1;
        int date = t.monthDay;
        int hour = t.hour; // 0-23
        int minute = t.minute;
        int second = t.second;
        if (month < 10)
            str = String.valueOf(year) + "0" + String.valueOf(month);
        else {
            str = String.valueOf(year) + String.valueOf(month);
        }
        if (date < 10)
            str = str + "0" + String.valueOf(date + "_");
        else {
            str = str + String.valueOf(date + "_");
        }
        if (hour < 10)
            str = str + "0" + String.valueOf(hour);
        else {
            str = str + String.valueOf(hour);
        }
        if (minute < 10)
            str = str + "0" + String.valueOf(minute);
        else {
            str = str + String.valueOf(minute);
        }
        if (second < 10)
            str = str + "0" + String.valueOf(second);
        else {
            str = str + String.valueOf(second);
        }
        return str;
    }
}


最后不要忘了,添加权限:

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

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值