Android Studio:使用Camera拍照(二)自定义相机

写在前面的话:每一个实例的代码都会附上相应的代码片或者图片,保证代码完整展示在博客中。最重要的是保证例程的完整性!!!方便自己也方便他人~欢迎大家交流讨论~

1.新建一个Android项目,取名为startcamera

java文件:startcamera.java主文件
Customcamera.java,ResultActivity.java
layout文件:activity_startcamera.xml,custom.xml,result.xml

2.处理界面布局

2.1activity_startcamera.xml

定义一个放置开始拍照按钮的界面

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    tools:context=".FirstActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="customCamera"
        android:text="@string/button_name" />

    <ImageView
        android:id="@+id/iv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

这里写图片描述

2.2custom.xml

这个界面有拍照按钮和实时预览界面

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/button_name1"
        android:onClick="capture"/>

    <SurfaceView
        android:id="@+id/preview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

这里写图片描述

2.3result.xml

这个界面用来显示拍照结果

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/pic"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

2.4strings.xml

<resources>
    <string name="app_name">startcamera</string>
    <string name="button_name">开始拍照</string>
    <string name="button_name1">capture</string>
</resources>

3.编辑代码

3.1startcamera.java

package com.example.administrator.startcamere;

import android.app.Activity;
import android.content.Intent;
import android.view.View;

public class startcamera extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_startcamera);
    }

    public void  customCamera(View view){
        startActivity(new Intent(this,Customcamera.class));
    }
}

3.2Customcamera.java

在这里编辑自定义相机的代码

package com.example.administrator.startcamere;

import android.app.Activity;
import android.content.Intent;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class Customcamera extends Activity implements SurfaceHolder.Callback{
    private Camera mCamera;
    private SurfaceView mPreview;
    private SurfaceHolder mHolder;
    private int cameraId=1;//声明cameraId属性,ID为1调用前置摄像头,为0调用后置摄像头。此处因有特殊需要故调用前置摄像头
    //定义照片保存并显示的方法
    private Camera.PictureCallback mpictureCallback=new Camera.PictureCallback(){
        @Override
        public void onPictureTaken(byte[] data,Camera camera){
          File tempfile=new File("/sdcard/emp.png");//新建一个文件对象tempfile,并保存在某路径中
          try{ FileOutputStream fos =new FileOutputStream(tempfile);
              fos.write(data);//将照片放入文件中
              fos.close();//关闭文件
              Intent intent=new Intent(Customcamera.this,ResultActivity.class);//新建信使对象
              intent.putExtra("picpath",tempfile.getAbsolutePath());//打包文件给信使
              startActivity(intent);//打开新的activity,即打开展示照片的布局界面
              Customcamera.this.finish();//关闭现有界面
          }
              catch (IOException e){e.printStackTrace();}
        }
    };
    @Override
    protected void onCreate( Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.custom);
        mPreview=findViewById(R.id.preview);//初始化预览界面
        mHolder=mPreview.getHolder();
        mHolder.addCallback(this);
        //点击预览界面聚焦
        mPreview.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCamera.autoFocus(null);
            }
        });
    }
   //定义“拍照”方法
    public void capture(View view){
        Camera.Parameters parameters=mCamera.getParameters();
        parameters.setPictureFormat(ImageFormat.JPEG);//设置照片格式
        parameters.setPreviewSize(800,400);
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        //摄像头聚焦
        mCamera.autoFocus(new Camera.AutoFocusCallback(){
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                if(success){mCamera.takePicture(null,null, mpictureCallback);}
            }
        });

}
//activity生命周期在onResume是界面应是显示状态
    @Override
    protected void onResume() {
        super.onResume();
        if (mCamera==null){//如果此时摄像头值仍为空
            mCamera=getCamera();//则通过getCamera()方法开启摄像头
            if(mHolder!=null){
                setStartPreview(mCamera,mHolder);//开启预览界面
            }
        }
    }
//activity暂停的时候释放摄像头
    @Override
    protected void onPause() {
        super.onPause();
        releaseCamera();
    }
    //onResume()中提到的开启摄像头的方法
    private Camera getCamera(){
        Camera camera;//声明局部变量camera
        try{
        camera=Camera.open(cameraId);}//根据cameraId的设置打开前置摄像头
        catch (Exception e){
            camera=null;
            e.printStackTrace(); }
        return camera;
    }
    //开启预览界面
    private void setStartPreview(Camera camera,SurfaceHolder holder){
        try{
        camera.setPreviewDisplay(holder);
        camera.setDisplayOrientation(90);//如果没有这行你看到的预览界面就会是水平的
        camera.startPreview();}
        catch (Exception e){
            e.printStackTrace(); }
    }
    //定义释放摄像头的方法
    private void releaseCamera(){
        if(mCamera!=null){//如果摄像头还未释放,则执行下面代码
            mCamera.stopPreview();//1.首先停止预览
            mCamera.setPreviewCallback(null);//2.预览返回值为null
            mCamera.release(); //3.释放摄像头
            mCamera=null;//4.摄像头对象值为null
        }
    }
    //定义新建预览界面的方法
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        setStartPreview(mCamera,mHolder);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        mCamera.stopPreview();//如果预览界面改变,则首先停止预览界面
        setStartPreview(mCamera,mHolder);//调整再重新打开预览界面
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        releaseCamera();//预览界面销毁则释放相机
    }
}

3.3ResultActivity.java

在这里编辑照片显示的代码

package com.example.administrator.startcamere;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.widget.ImageView;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

public class ResultActivity extends Activity {
    @Override
    protected void onCreate( Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.result);
        String path=getIntent().getStringExtra("picpath");//通过值"picpath"得到照片路径
        ImageView imageview=findViewById(R.id.pic);
        try{FileInputStream fis=new FileInputStream(path);
        Bitmap bitmap=BitmapFactory.decodeStream(fis);
        Matrix matrix=new Matrix();//新建一个矩阵对象
        matrix.setRotate(270);//矩阵旋转操作让照片可以正对着你。但是还存在一个左右对称的问题
        bitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
        imageview.setImageBitmap(bitmap);}
        catch (FileNotFoundException e){e.printStackTrace();}
        //Bitmap bitmap=BitmapFactory.decodeFile(path);
    }
}

4.AndroidManifest.xml

新增下列代码,设置用户权限

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

注册activity,否则系统找不到你另外新建的两个activity会报错

<activity android:name=".Customcamera"/>
<activity android:name=".ResultActivity"/>

附:&官方文档
https://developer.android.google.cn/guide/topics/media/camera#saving-media
&学习的原视频教程地址Android摄像头基础https://www.imooc.com/learn/543

猜你喜欢

转载自blog.csdn.net/Leo_Huang720/article/details/81289309