本讲内容:Android手机摄像头编程入门智能手机中的摄像头和普通手机中的摄像头最大的区别在于,智能机上的摄像头可以由程序员写程序控制, 做一些有趣的应用譬如,画中画,做一些有用的应用譬如二维码识别,等等。本讲打算通过一个实例,来介绍一下摄像头编程,相关解释都写在代码中了,请注意看 代码注释。

  实例:窈窈照相机,功能很简单,就是点击程序弹出照相预览界面,点击相机按钮完成照相功能,所照相片会存储在手机存储卡根目录。

  1、创建一个项目 Lesson36_Camera ,主程序文件为 MainActivity.java2、AndroidManifest.xml 中设置屏幕为横屏,并且声明摄像头和存储卡的使用权限,具体代码如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest package="basic.android.lesson36"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:versioncode="1" android:versionname="1.0">
  3. <application android:label="@string/app_name" android:icon="@drawable/icon">
  4. <activity android:label="@string/app_name"
    android:name=".MainActivity" android:screenorientation="landscape"
    android:configchanges="orientation|keyboardHidden|keyboard">
  5. <intent -filter="">
  6. <action android:name="android.intent.action.MAIN">
  7. <category android:name="android.intent.category.LAUNCHER">
  8. </category></action></intent>
  9. </activity>
  10. </application>
  11. <uses -sdk="" android:minsdkversion="8">
  12. <uses -permission="" android:name="android.permission.CAMERA"></uses>
  13. <uses -permission="" android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses>
  14. <uses -feature="" android:name="android.hardware.camera">
  15. <uses -feature="" android:name="android.hardware.camera.autofocus">
  16. </uses></uses></uses></manifest>

复制代码

  3、本例中不需要布局文件main.xml,因为本例中的UI组建都是动态添加上去的。

  4、最后MainActivity.java的代码如下:

  1. package basic.android.lesson36;
  2. import java.io.BufferedOutputStream;
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.util.Calendar;
  7. import java.util.Locale;
  8. import android.app.Activity;
  9. import android.content.Context;
  10. import android.graphics.Bitmap;
  11. import android.graphics.BitmapFactory;
  12. import android.graphics.PixelFormat;
  13. import android.hardware.Camera;
  14. import android.os.Bundle;
  15. import android.text.format.DateFormat;
  16. import android.util.Log;
  17. import android.view.KeyEvent;
  18. import android.view.SurfaceHolder;
  19. import android.view.SurfaceView;
  20. import android.view.Window;
  21. import android.view.WindowManager;
  22. import android.widget.FrameLayout;
  23. import android.widget.TextView;
  24. import android.widget.Toast;
  25. public class MainActivity extends Activity {
  26. private CameraView cv;
  27. //准备一个相机对象
  28. private Camera mCamera = null;
  29. //准备一个Bitmap对象
  30. private Bitmap mBitmap = null;
  31. //准备一个保存图片的PictureCallback对象
  32. public Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
  33. public void onPictureTaken(byte[] data, Camera camera) {
  34. Log.i("yao","onPictureTaken");
  35. Toast.makeText(getApplicationContext(), "正在保存……", Toast.LENGTH_LONG).show();
  36. //用BitmapFactory.decodeByteArray()方法可以把相机传回的裸数据转换成Bitmap对象
  37. mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
  38. //接下来的工作就是把Bitmap保存成一个存储卡中的文件
  39. File file = new File("/sdcard/YY"+ new
    DateFormat().format("yyyyMMdd_hhmmss",
    Calendar.getInstance(Locale.CHINA)) + ".jpg");
  40. try {
  41. file.createNewFile();
  42. BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file));
  43. mBitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
  44. os.flush();
  45. os.close();
  46. Toast.makeText(getApplicationContext(), "图片保存完毕,在存储卡的根目录", Toast.LENGTH_LONG).show();
  47. } catch (IOException e) {
  48. e.printStackTrace();
  49. }
  50. }
  51. };
  52. //Activity的创建方法
  53. @Override
  54. public void onCreate(Bundle savedInstanceState) {
  55. super.onCreate(savedInstanceState);
  56. //窗口去掉标题
  57. requestWindowFeature(Window.FEATURE_NO_TITLE);
  58. //窗口设置为全屏
  59. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
  60. //设置窗口为半透明
  61. getWindow().setFormat(PixelFormat.TRANSLUCENT);
  62. //提供一个帧布局
  63. FrameLayout  fl = new FrameLayout(this);
  64. //创建一个照相预览用的SurfaceView子类,并放在帧布局的底层
  65. cv = new CameraView(this);
  66. fl.addView(cv);
  67. //创建一个文本框添加在帧布局中,我们可以看到,文字自动出现在了SurfaceView的前面,由此你可以在预览窗口做出各种特殊效果
  68. TextView tv = new TextView(this);
  69. tv.setText("请按\"相机\"按钮拍摄");
  70. fl.addView(tv);
  71. //设置Activity的根内容视图
  72. setContentView(fl);
  73. }
  74. //相机按键按下的事件处理方法
  75. public boolean onKeyDown(int keyCode, KeyEvent event) {
  76. Log.i("yao","MainActivity.onKeyDown");
  77. if (keyCode == KeyEvent.KEYCODE_CAMERA) {
  78. if (mCamera != null) {
  79. Log.i("yao","mCamera.takePicture");
  80. //当按下相机按钮时,执行相机对象的takePicture()方法,该方法有三个回调对象做入参,不需要的时候可以设null
  81. mCamera.takePicture(null, null, pictureCallback);
  82. }
  83. }
  84. return cv.onKeyDown(keyCode, event);
  85. }
  86. // 照相视图
  87. class CameraView extends SurfaceView {
  88. private SurfaceHolder holder = null;
  89. //构造函数
  90. public CameraView(Context context) {
  91. super(context);
  92. Log.i("yao","CameraView");
  93. // 操作surface的holder
  94. holder = this.getHolder();
  95. // 创建SurfaceHolder.Callback对象
  96. holder.addCallback(new SurfaceHolder.Callback() {
  97. @Override
  98. public void surfaceDestroyed(SurfaceHolder holder) {
  99. // 停止预览
  100. mCamera.stopPreview();
  101. // 释放相机资源并置空
  102. mCamera.release();
  103. mCamera = null;
  104. }
  105. @Override
  106. public void surfaceCreated(SurfaceHolder holder) {
  107. //当预览视图创建的时候开启相机
  108. mCamera = Camera.open();
  109. try {
  110. //设置预览
  111. mCamera.setPreviewDisplay(holder);
  112. } catch (IOException e) {
  113. // 释放相机资源并置空
  114. mCamera.release();
  115. mCamera = null;
  116. }
  117. }
  118. //当surface视图数据发生变化时,处理预览信息
  119. @Override
  120. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  121. //获得相机参数对象
  122. Camera.Parameters parameters = mCamera.getParameters();
  123. //设置格式
  124. parameters.setPictureFormat(PixelFormat.JPEG);
  125. //设置预览大小,这里我的测试机是Milsstone所以设置的是854x480
  126. parameters.setPreviewSize(854, 480);
  127. //设置自动对焦
  128. parameters.setFocusMode("auto");
  129. //设置图片保存时的分辨率大小
  130. parameters.setPictureSize(2592, 1456);
  131. //给相机对象设置刚才设定的参数
  132. mCamera.setParameters(parameters);
  133. //开始预览
  134. mCamera.startPreview();
  135. }
  136. });
  137. // 设置Push缓冲类型,说明surface数据由其他来源提供,而不是用自己的Canvas来绘图,在这里是由摄像头来提供数据
  138. holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  139. }
  140. }
  141. }

复制代码

  5、连接Milestone,编译并运行程序:悲剧的是,截图只能看到黑黑的一片,无法截取到摄像头传输过来SurfaceView信息,而在真机中是能看到预览效果的。

Android手机摄像头编程入门的更多相关文章

  1. ORB-SLAM2 运行 —— ROS + Android 手机摄像头

    转载请注明出处,谢谢 原创作者:Mingrui 原创链接:https://www.cnblogs.com/MingruiYu/p/12404730.html 本文要点: ROS 配置安装 解决 sud ...

  2. DSO 运行 —— dso_ros + Android 手机摄像头

    转载请注明出处,谢谢 原创作者:Mingrui 原创链接:https://www.cnblogs.com/MingruiYu/p/12425855.html 本文要点: dso 配置安装 dso 离线 ...

  3. 关于降低android手机摄像头预览分辨率

    假设现在有这样一个需求需要一直开着手机摄像头 但是不做任何拍照动作 但是每个手机的相机分辨率都不同 而默认预览的时候参数是最大分辨率 这样有时候就回导致电量损耗的加快 所以我们可以采取降低相机分辨率的 ...

  4. Android Native jni 编程入门

    在某些情况下,java编程已经不能满足我们的需要,比如一个复杂的算法处理,这时候就需要用到jni(java native interface)技术: jni 其实就是java和c/cpp之间进行通信的 ...

  5. 《Delphi XE6 android 编程入门教程》推荐

    近5.6年已经没有看见关于delphi的新技术的书出来了(看来在国内delphi的使用量确实很低了), 高勇同学最近出了一本<Delphi XE6 android 编程入门教程>,上周刚拿 ...

  6. Android系统编程入门系列之应用环境及开发环境介绍

        作为移动端操作系统,目前最新的Android 11.0已经发展的比较完善了,现在也到了系统的整理一番的时间,接下来的系列文章将以Android开发者为中心,争取用归纳总结的态度对初级入门者所应 ...

  7. Android系统编程入门系列之加载界面Activity

    上回说到应用初始化加载及其生命周期,在Android系统调用Applicaiton.onCreate()之后,继续创建并加载清单文件中注册的首个界面即主Activity,也可称之为入口界面.主Acti ...

  8. [电子书] 《Android编程入门很简单》

    <Android编程入门很简单>是一本与众不同的Android学习读物,是一本化繁为简,把抽象问题具体化,把复杂问题简单化的书.本书避免出现云山雾罩.晦涩难懂的讲解,代之以轻松活泼.由浅入 ...

  9. android 通过wifi 热点实现手机摄像头数据共享(转)

    原文地址:http://blog.csdn.net/sinat_35845281/article/details/52674946 最近想搞一个新奇的玩意儿~~~ 最近一直在在学习通过两个Androi ...

随机推荐

  1. linux命令:文件搜索命令

    ---恢复内容开始--- 文件搜索命令:which 命令名称:which 命令所在路径:/usr/bin/which 执行权限:所有用户 语法:which  [命令名称] 功能描述:显示系统命令所在目 ...

  2. Leetcode: Construct Binary Tree from Preorder and Inorder Transversal

    Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume that ...

  3. FastDFS单节点安装 & FastDFS+Nginx整合

    安装环境    FastDFS_v5.05.tar.gz(http://sourceforge.net/projects/fastdfs/files/)    fastdfs-nginx-module ...

  4. Linux服务器---安装mysql

    安装mysql 1.检测是否已安装mysql [root@localhost bin]# rpm -qa | grep mysql mysql-libs-5.1.71-1.el6.i686 [root ...

  5. Linux基础命令---ln

    ln 为指定的目录或者文件创建链接,如果没有指定链接名,那么会创建一个和源文件名字一样的链接. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fed ...

  6. Web API设计方法论--比较完整的web api 开发过程

    为Web设计.实现和维护API不仅仅是一项挑战:对很多公司来说,这是一项势在必行的任务.本系列将带领读者走过一段旅程,从为API确定业务用例到设计方法论,解决实现难题,并从长远的角度看待在Web上维护 ...

  7. mysql 从数据库中获取多条记录,二维展示数据

    展示要求: 客户/日期 2017-10-16 1017-10-17 2017-10-18 客户1       客户2       数据库中数据: 解决办法: 1.新建一个实体类:客户名称.客户数据(A ...

  8. nginx作防盗链设置

    盗链是一种损害原有网站合法权益,给原网站所在服务器造成额外负担的非法行为. 盗链的实现原理: 客户端向服务器请求资源时,为了减少网络带宽,提高响应时间,服务器一般不会一次将所有资源完整地传回给客户端. ...

  9. 从Oracle到MySQL,余额宝云实践分享

    原文链接:http://www.csdn.net/article/2013-11-/2817426-interview-financial-case-yuerbao-aliyun07 余额宝.百度百发 ...

  10. ubuntu服务器 安装 seafile 个人网盘

    目录 ubuntu服务器 安装 seafile 个人网盘 一.实验环境: 二.实验流程介绍 三.网盘搭建 1.安装依赖环境 2.安装seafile 三.配置QQ域名邮箱 四.配置seafile邮件服务 ...