这篇博客为大家介绍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;
            }
        }
    }

希望大家理解核心代码的详细注释,欢迎提供意见,希望能给大家带来帮助,谢谢!

源码:http://pan.baidu.com/s/1kVSBEK3

Android—实现自定义相机倒计时拍照的更多相关文章

  1. 如何用uniapp+vue开发自定义相机插件——拍照+录像功能

    调用手机的相机功能并实现拍照和录像是很多APP与插件都必不可少的一个功能,今天智密科技就来分享一下如何基于uniapp + vue实现自定义相机界面,并且实现: 1: 自定义拍照 2: 自定义录像 3 ...

  2. Android相机使用(系统相机、自定义相机、大图片处理)

    本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显示出来,该例子也会涉及到Android加载大图片时候的处理(避免OOM),还有简要提一下有些人Surf ...

  3. Android调用系统相机、自定义相机、处理大图片

    Android调用系统相机和自定义相机实例 本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显示出来,该例子也会涉及到Android加载大图片时候的处理 ...

  4. Android调用系统相机、自己定义相机、处理大图片

    Android调用系统相机和自己定义相机实例 本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,而且因为涉及到要把拍到的照片显示出来,该样例也会涉及到Android载入大图片时候的处 ...

  5. Android自定义相机拍照、图片裁剪的实现

    最近项目里面又要加一个拍照搜题的功能,也就是用户对着不会做的题目拍一张照片,将照片的文字使用ocr识别出来,再调用题库搜索接口搜索出来展示给用户,类似于小猿搜题.学霸君等app. 其实Android提 ...

  6. Android Multimedia框架总结(十四)Camera框架初识及自定义相机案例

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52738492 前言:国庆节告一段 ...

  7. Android实现自定义的相机

    使用系统相机 android中使用系统相机是很方便的,单这仅仅是简单的使用而已,并不能获得什么特殊的效果. 要想让应用有相机的action,咱们就必须在清单文件中做一些声明,好让系统知道,如下 < ...

  8. Android Camera开发系列(下)——自定义Camera实现拍照查看图片等功能

    Android Camera开发系列(下)--自定义Camera实现拍照查看图片等功能 Android Camera开发系列(上)--Camera的基本调用与实现拍照功能以及获取拍照图片加载大图片 上 ...

  9. android 自定义相机

    老规矩,先上一下项目地址:GitHub:https://github.com/xiangzhihong/CameraDemo 方式: 调用Camera API 自定义相机 调用系统相机 由于需求不同, ...

随机推荐

  1. 创建外网 ext_net - 每天5分钟玩转 OpenStack(104)

    虽然外部网络是已经存在的网络,但我们还是需要在 Neutron 中定义外部网络的对象,这样 router 才知道如何将租户网络和外部网络连接起来. 上一节我们已经为创建外部网络配置了ML2,本节将通过 ...

  2. ASP.NET MVC之表单集合数据自动绑定到对象属性(集合)中

    前言 之前没遇到过这个问题,在项目中遇到这个问题时想法挺好,按照流程走下去,结果事与愿违,于是开始探索着解决方案,接下来我们来看看这个问题,早已经明了的童鞋请绕道,此文仅供未遇到的童鞋提供一种解决方案 ...

  3. 最大值最小化(DP)

    题目来源:网易有道2013年校园招聘面试一面试题 题目描述: 在印刷术发明之前,复制一本书是一个很困难的工作,工作量很大,而且需要大家的积极配合来抄写一本书,团队合作能力很重要.当时都是通过招募抄写员 ...

  4. swift 新特性

    switch支持任意类型的数据以及各种比较操作——不仅仅是整数以及测试相等. 运行switch中匹配到的子句之后,程序会退出switch语句,并不会继续向下运行,所以不需要在每个子句结尾写break. ...

  5. UML中的六大关系(转)

    UML定义的关系主要有六种:依赖.继承.关联.实现.聚合和组合.这些类间关系的理解和使用是掌握和应用UML的关键,而也就是这几种关系,往往会让初学者迷惑.这里给出这六种主要UML关系的说明和类图描述, ...

  6. IOS客户端UIwebview下web页面闪屏问题

    基于ios客户端uiwebview下的web页面,在其内容高度大于视窗高度时,如果点击超过视窗下文档的底部按钮,收缩内容高度,会发生闪屏问题. 外因是由文档的高度大于视窗的高度所致,本质原因未知. 解 ...

  7. C#使用iTextSharp给PDF添加水印

    代码: /// <summary> /// 添加普通偏转角度文字水印 /// </summary> public static void SetWatermark(string ...

  8. PetaPoco4.0 实体某个字段不赋值会更新成null解决方案

    最新用PetaPoco4.0做项目发现有个需求,就是比如说:在mvc表单中,只显示部分字段,一个表单还有其他状态等字段,没有显示到mvc页面上 但是当MVC收集表单提交更新的时候,会发现会把数据库中的 ...

  9. 基础笔记(三):网络协议之Tcp、Http

    目录 一.网络协议 二.TCP(Transmission Control Protocol,传输控制协议) TCP头格式 TCP协议中的三次握手和四次挥手 TCP报文抓取工具 三.HTTP(Hyper ...

  10. Redis 学习笔记(C#)

    Redis安装及简单操作 Windows下安装步骤: 1. 第一步当然是先下载咯~  地址:https://github.com/dmajkic/redis/downloads (根据自己实际情况选择 ...