这篇博客为大家介绍Android自定义相机,并且实现倒计时拍照功能

首先自定义拍照会用到SurfaceView控件显示照片的预览区域,以下是布局文件:

两个TextView是用来显示提示信息和倒计时的秒数的

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="#266194"
  6. android:orientation="vertical"
  7. tools:context=".TestActivity" >
  8.  
  9. <SurfaceView
  10. android:id="@+id/surfaceView"
  11. android:layout_width="match_parent"
  12. android:layout_height="match_parent"
  13. android:layout_centerInParent="true" />
  14.  
  15. <LinearLayout
  16. android:layout_width="wrap_content"
  17. android:layout_height="wrap_content"
  18. android:layout_centerInParent="true"
  19. android:orientation="vertical" >
  20.  
  21. <TextView
  22. android:layout_width="match_parent"
  23. android:layout_height="wrap_content"
  24. android:text="请调整位置到此区域"
  25. android:textColor="#ff0000"
  26. android:textSize="32sp" />
  27.  
  28. <TextView
  29. android:id="@+id/tv_time"
  30. android:layout_width="match_parent"
  31. android:layout_height="wrap_content"
  32. android:paddingTop="10dp"
  33. android:gravity="center_horizontal"
  34. android:textColor="#266194"
  35. android:textSize="32sp" />
  36. </LinearLayout>
  37.  
  38. </RelativeLayout>

接下来是mainActivity中的具体实现以及详细注释:

  1. package com.dhsr.pujiejia.ui;
  2.  
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.text.SimpleDateFormat;
  6. import java.util.Date;
  7.  
  8. import android.annotation.SuppressLint;
  9. import android.app.Activity;
  10. import android.content.Context;
  11. import android.content.Intent;
  12. import android.content.res.Configuration;
  13. import android.graphics.Bitmap;
  14. import android.graphics.BitmapFactory;
  15. import android.graphics.PixelFormat;
  16. import android.hardware.Camera;
  17. import android.hardware.Camera.CameraInfo;
  18. import android.os.Bundle;
  19. import android.os.Environment;
  20. import android.os.Handler;
  21. import android.view.SurfaceHolder;
  22. import android.view.SurfaceView;
  23. import android.view.Window;
  24. import android.view.WindowManager;
  25. import android.widget.TextView;
  26.  
  27. import com.example.pujiejiaapp.R;
  28.  
  29. @SuppressLint({ "NewApi", "SdCardPath" })
  30. public class CameraActivity extends Activity implements Runnable {
  31. // 预览图片范围
  32. private SurfaceView surfaceView;
  33. private TextView tv_time;
  34. // 倒计时拍摄
  35. private int cameratime = 4;
  36. private Camera camera;
  37. private boolean preview = false;
  38. // 文件名字
  39. private String filename;
  40. // 文件名字的带的时间戳
  41. private String timeString;
  42. // 格式化时间
  43. private SimpleDateFormat dateFormat;
  44. // 日期对象
  45. private Date date;
  46. // 控制线程
  47. boolean stopThread = false;
  48. private File file;
  49. String photo;
  50.  
  51. private Handler mHandler = new Handler() {
  52. public void handleMessage(android.os.Message msg) {
  53. int what = msg.what;
  54. switch (what) {
  55. case 222:
  56. tv_time.setText("" + cameratime);
  57. if ("0".equals(tv_time.getText().toString())) {
  58. tv_time.setText("拍摄成功!");
  59. takePhoto();
  60. }
  61. break;
  62.  
  63. }
  64. };
  65. };
  66.  
  67. @Override
  68. protected void onCreate(Bundle savedInstanceState) {
  69. // TODO Auto-generated method stub
  70. super.onCreate(savedInstanceState);
  71. setContentView(R.layout.activity_test);
  72. CameraActivity.this.setFinishOnTouchOutside(false);
  73. // 初始化数据
  74. findView();
  75. surfaceView.getHolder().addCallback(new SufaceListener());
  76. /* 下面设置Surface不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前 */
  77. surfaceView.getHolder()
  78. .setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  79. surfaceView.getHolder().setFixedSize(200, 200); // 设置分辨率
  80. }
  81.  
  82. @Override
  83. protected void onStart() {
  84. // TODO Auto-generated method stub
  85. super.onStart();
  86. // 开启线程
  87. new Thread(this).start();
  88. }
  89.  
  90. private final class SufaceListener implements SurfaceHolder.Callback {
  91. /**
  92. * surface改变
  93. */
  94. @Override
  95. public void surfaceChanged(SurfaceHolder holder, int format, int width,
  96. int height) {
  97. }
  98.  
  99. /**
  100. * surface创建
  101. */
  102. @Override
  103. public void surfaceCreated(SurfaceHolder holder) {
  104. try {
  105. for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
  106. CameraInfo info = new CameraInfo();
  107. Camera.getCameraInfo(i, info);
  108. // 调用系统的前置摄像头
  109. if (info.facing == CameraInfo.CAMERA_FACING_FRONT) {
  110. camera = Camera.open(i);
  111. }
  112. }
  113. Camera.Parameters parameters = camera.getParameters();
  114. /* 每秒从摄像头捕获5帧画面, */
  115. parameters.setPreviewFrameRate(5);
  116. /* 设置照片的输出格式:jpg */
  117. parameters.setPictureFormat(PixelFormat.JPEG);
  118. /* 照片质量 */
  119. parameters.set("jpeg-quality", 85);
  120. WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
  121. camera.setParameters(parameters);
  122. camera.setPreviewDisplay(surfaceView.getHolder());// 通过SurfaceView显示取景画面
  123. camera.startPreview();
  124. preview = true;
  125. } catch (Exception e) {
  126.  
  127. }
  128. }
  129.  
  130. /**
  131. * surface销毁
  132. */
  133. @Override
  134. public void surfaceDestroyed(SurfaceHolder holder) {
  135. if (camera != null) {
  136. if (preview)
  137. camera.stopPreview();
  138. camera.release();
  139. camera = null;
  140. }
  141. }
  142. }
  143.  
  144. /**
  145. * 拍摄照片
  146. */
  147. private void takePhoto() {
  148. // 执行拍照效果
  149. camera.takePicture(null, null, new Camera.PictureCallback() {
  150. @Override
  151. public void onPictureTaken(byte[] data, Camera camera) {
  152. try {
  153. Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
  154. data.length);
  155. timeString = formatDate();
  156. //保存到data/data目录自定义文件夹下
  157. filename = "/data/data/com.example.pujiejiaapp/images/"
  158. + timeString + ".jpg";
  159. File file = new File(filename);
  160. boolean createNewFile = file.createNewFile()
  161. System.out.println("创建文件夹成功没有" + createNewFile);
  162. System.out.println(file);
  163. FileOutputStream outStream = new FileOutputStream(file);
  164. bitmap.compress(Bitmap.CompressFormat.JPEG, 60, outStream);
  165. outStream.flush();
  166. outStream.close();
  167. // 重新浏览
  168. camera.stopPreview();
  169. camera.startPreview();
  170. preview = true;
  171. } catch (Exception e) {
  172. e.printStackTrace();
  173. } finally {
  174. }
  175. }
  176. });
  177. }
  178.  
  179. @Override
  180. public void run() {
  181. while (!stopThread) {
  182. try {
  183. //按秒数倒计时
  184. Thread.sleep(1000);
  185. } catch (InterruptedException e) {
  186. // TODO Auto-generated catch block
  187. e.printStackTrace();
  188. }
  189. cameratime--;
  190. mHandler.sendEmptyMessage(222);
  191. if (cameratime <= 0) {
  192. break;
  193. }
  194. }
  195. }
  196.  
  197. // 初始化数据
  198. private void findView() {
  199. surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView);
  200. tv_time = (TextView) findViewById(R.id.tv_time);
  201. }
  202.  
  203. // 格式化系统的时间
  204. public String formatDate() {
  205. date = new Date(System.currentTimeMillis());
  206. // 日期格式
  207. dateFormat = new SimpleDateFormat("'IMG'_yyyyMMddHHmmss");
  208. return dateFormat.format(date);
  209. }
  210.  
  211. @Override
  212. protected void onDestroy() {
  213. // TODO Auto-generated method stub
  214. // 线程已关闭
  215. super.onDestroy();
  216. stopThread = true;
  217. }
  218.  
  219. }

核心代码详解:

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. 深入浏览器兼容 细数jQuery Hooks 属性篇

    关于钩子:http://www.cnblogs.com/aaronjs/p/3387906.html 本章的目的很简单,通过钩子函数更细节的了解浏览器差异与处理方案, 版本是2.0.3所以不兼容ie6 ...

  2. Change Line Type in OpenCascade

    Change Line Type in OpenCascade eryar@163.com 关键字KeyWords:OpenCascade,Line Aspect, Line Type 在OpenCa ...

  3. WPF调用Matlab函数方法

    有的时候用C#写图像处理方法,比较费事,不如Matlab简单,但是Matlab又做不出WPF那样的好看界面,怎么办呢. 今天正好我要实现这个功能,就顺便写个小例子,给需要的人做个借鉴. 想要用WPF调 ...

  4. 前端学PHP之字符串函数

    × 目录 [1]特点 [2]输出 [3]空格[4]大小写[5]HTML[6]格式化[7]比较 前面的话 字符串的处理和分析在任何编程语言中都是一个重要的基础,往往是简单而重要的.信息的分类.解析.存储 ...

  5. Snapshot Volume 操作 - 每天5分钟玩转 OpenStack(58)

    Snapshot 可以为 volume 创建快照,快照中保存了 volume 当前的状态,以后可以通过 snapshot 回溯.snapshot 操作实现比较简单,流程图如下: 向 cinder-ap ...

  6. 重磅开源:TN文本分析语言

    tn是desert(沙漠之鹰)和tan共同开发的一种用于匹配,转写和抽取文本的语言(DSL).并为其开发和优化了专用的编译器.基于递归下降方法和正则表达式,能解析自然文本并转换为树和字典,识别时间,地 ...

  7. spring源码分析之spring-core总结篇

    1.spring-core概览 spring-core是spring框架的基石,它为spring框架提供了基础的支持. spring-core从源码上看,分为6个package,分别是asm,cgli ...

  8. 关于IE6的PNG图像透明使用AlphaImageLoader的缺点

    PNG32的alpha透明效果在IE6下会出现bug,出现灰色背景.而目前的解决方案就是 IE提供的滤镜.需要注意的是滤镜并不是对原图片进行修改,而是对相应的html元素进行 修改.所以在一个html ...

  9. Masonry_设置比例

    [self.bgView addSubview:self.progressImageView]; [self.progressImageView mas_makeConstraints:^(MASCo ...

  10. WebSocket 介绍(二)-WebSocket API

    这一章介绍如何用WebSocket API来控制协议和创建应用,运用http://websocket.org 提供的现有WebSocket服务器,我们可以收发消息.创建一些简单的WebSocket应用 ...