Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android—實現自定義相機倒計時拍照,android自定義

Android—實現自定義相機倒計時拍照,android自定義

編輯:關於android開發

Android—實現自定義相機倒計時拍照,android自定義


這篇博客為大家介紹Android自定義相機,並且實現倒計時拍照功能

首先自定義拍照會用到SurfaceView控件顯示照片的預覽區域,以下是布局文件:

兩個TextView是用來顯示提示信息和倒計時的秒數的

<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:background="#266194"
    android:orientation="vertical"
    tools:context=".TestActivity" >

    <SurfaceView
        android:id="@+id/surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:orientation="vertical" >

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="請調整位置到此區域"
            android:textColor="#ff0000"
            android:textSize="32sp" />

        <TextView
            android:id="@+id/tv_time"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="10dp"
            android:gravity="center_horizontal"
            android:textColor="#266194"
            android:textSize="32sp" />
    </LinearLayout>

</RelativeLayout>

接下來是mainActivity中的具體實現以及詳細注釋:

package com.dhsr.pujiejia.ui;

import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;

import com.example.pujiejiaapp.R;

@SuppressLint({ "NewApi", "SdCardPath" })
public class CameraActivity extends Activity implements Runnable {
    // 預覽圖片范圍
    private SurfaceView surfaceView;
    private TextView tv_time;
    // 倒計時拍攝
    private int cameratime = 4;
    private Camera camera;
    private boolean preview = false;
    // 文件名字
    private String filename;
    // 文件名字的帶的時間戳
    private String timeString;
    // 格式化時間
    private SimpleDateFormat dateFormat;
    // 日期對象
    private Date date;
    // 控制線程
    boolean stopThread = false;
    private File file;
    String photo;

    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            int what = msg.what;
            switch (what) {
            case 222:
                tv_time.setText("" + cameratime);
                if ("0".equals(tv_time.getText().toString())) {
                    tv_time.setText("拍攝成功!");
                    takePhoto();
                }
                break;

            }
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        CameraActivity.this.setFinishOnTouchOutside(false);
        // 初始化數據
        findView();
        surfaceView.getHolder().addCallback(new SufaceListener());
        /* 下面設置Surface不維護自己的緩沖區,而是等待屏幕的渲染引擎將內容推送到用戶面前 */
        surfaceView.getHolder()
                .setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceView.getHolder().setFixedSize(200, 200); // 設置分辨率
    }

    @Override
    protected void onStart() {
        // TODO Auto-generated method stub
        super.onStart();
        // 開啟線程
        new Thread(this).start();
    }

    private final class SufaceListener implements SurfaceHolder.Callback {
        /**
         * surface改變
         */
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width,
                int height) {
        }

        /**
         * surface創建
         */
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            try {
                for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
                    CameraInfo info = new CameraInfo();
                    Camera.getCameraInfo(i, info);
                    // 調用系統的前置攝像頭
                    if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                        camera = Camera.open(i);
                    }
                }
                Camera.Parameters parameters = camera.getParameters();
                /* 每秒從攝像頭捕獲5幀畫面, */
                parameters.setPreviewFrameRate(5);
                /* 設置照片的輸出格式:jpg */
                parameters.setPictureFormat(PixelFormat.JPEG);
                /* 照片質量 */
                parameters.set("jpeg-quality", 85);
                WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
                camera.setParameters(parameters);
                camera.setPreviewDisplay(surfaceView.getHolder());// 通過SurfaceView顯示取景畫面
                camera.startPreview();
                preview = true;
            } catch (Exception e) {

            }
        }

        /**
         * surface銷毀
         */
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            if (camera != null) {
                if (preview)
                    camera.stopPreview();
                camera.release();
                camera = null;
            }
        }
    }

    /**
     * 拍攝照片
     */
    private void takePhoto() {
        // 執行拍照效果
        camera.takePicture(null, null, new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                try {
                    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
                            data.length);
                    timeString = formatDate();
                    //保存到data/data目錄自定義文件夾下
                     filename = "/data/data/com.example.pujiejiaapp/images/"
                     + timeString + ".jpg";
                    File file = new File(filename);
                    boolean createNewFile = file.createNewFile()
                    System.out.println("創建文件夾成功沒有" + createNewFile);
                    System.out.println(file);
                    FileOutputStream outStream = new FileOutputStream(file);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 60, outStream);
                    outStream.flush();
                    outStream.close();
                    // 重新浏覽
                    camera.stopPreview();
                    camera.startPreview();
                    preview = true;
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                }
            }
        });
    }

    @Override
    public void run() {
        while (!stopThread) {
            try {
                //按秒數倒計時
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            cameratime--;
            mHandler.sendEmptyMessage(222);
            if (cameratime <= 0) {
                break;
            }
        }
    }

    // 初始化數據
    private void findView() {
        surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView);
        tv_time = (TextView) findViewById(R.id.tv_time);
    }

    // 格式化系統的時間
    public String formatDate() {
        date = new Date(System.currentTimeMillis());
        // 日期格式
        dateFormat = new SimpleDateFormat("'IMG'_yyyyMMddHHmmss");
        return dateFormat.format(date);
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        // 線程已關閉
        super.onDestroy();
        stopThread = true;
    }

}

核心代碼詳解:

1.創建SurfaceView時,surfaceCreated()方法中

for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
                    CameraInfo info = new CameraInfo();
                    Camera.getCameraInfo(i, info);
                    // 調用系統的前置攝像頭
                    if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
                        camera = Camera.open(i);
                    }
                }

此部分代碼為打開相機時默認打開前置攝像頭CameraInfo.CAMERA_FACING_BACK為默認打開後置攝像頭,CameraInfo.CAMERA_FACING_FRONT前置攝像頭

2.照片拍攝takePhoto()方法中:

Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
                            data.length);
                    timeString = formatDate();
                     filename = "/data/data/com.example.pujiejiaapp/images/"
                     + timeString + ".jpg";
                    photo = timeString + ".jpg";
                    File file = new File(filename);
                    boolean createNewFile = file.createNewFile();
                    FileOutputStream outStream = new FileOutputStream(file);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 60, outStream);

此部分代碼為將拍攝到的圖片保存為以bitmap格式保存在指定的目錄下

3.開子線程用於倒計時拍攝

public void run() {
        while (!stopThread) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            cameratime--;
            mHandler.sendEmptyMessage(222);
            if (cameratime <= 0) {
                break;
            }
        }
    }

希望大家理解核心代碼的詳細注釋,歡迎提供意見,希望能給大家帶來幫助,謝謝!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved