本讲内容: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. win 7 和 winserver 2008 下,布署网站遇到的错误解决方法

    本人亲测,有效. 1.如果只列出目录: web.config的system.webServer配置节下是否有这个: <modules runAllManagedModulesForAllRequ ...

  2. GCC编译器ABI

    ABI与EABI 1)ABI(Application Binary Interface for the ARM Architecture),描述了应用程序与cpu内核的低级接口. ABI允许编译好的目 ...

  3. vue 渲染页面的时候 出现闪烁问题的解决办法

    在使用vue绑定数据的时候,渲染页面时会出现变量闪烁 <div id="h_cameraman" v-cloak> <public-nav> {{ msg ...

  4. sql server 数据排名

    城市排名列表 )) AS px, ) pm25, ) pm10, ) co, ) no2, ) so2,) o3_8,) indexs,) aqi FROM monitor_city_hour m,c ...

  5. python-随机数的产生random模块

    random模块用来产生随机数: 查看random模块的方法: import random random.__dir__ Out[39]: <function __dir__> rando ...

  6. adb shell 命令详解,android, adb logcat

    http://www.miui.com/article-275-1.html http://noobjava.iteye.com/blog/1914348 adb shell 命令详解,android ...

  7. BIOS、MBR、UEFI和GPT关系

    很多用户在新买电脑,或是给已有电脑重装系统时都出现过怎么都无法引导U盘安装的情况.究其原因,还是没能搞清楚BIOS.MBR.UEFI和GPT的复杂关系.所以,今天小编就和大家分享一下它们之间的爱恨情仇 ...

  8. JavaScript:正则表达式 分组2

    继续上一篇的写,这篇复杂点. 分组+范围 var reg=/([abcd]bc)/g; var str="abcd bbcd cbcd dbcd"; console.log(str ...

  9. Springboot2.x 集成redis

    pom.xml 添加 <dependency> <groupId>org.springframework.boot</groupId> <artifactId ...

  10. 【文件readonly异常】异常退出编译文件,再次进入提示readonly

    1.对于同一个文件如果上次已经打开,而未关闭的情况下,又打开该文件进行编辑时,会出现如下提醒: 这是由于已经打开但未闭关的文件,会在其目录下出现一个.swp的文件,由于是属于隐藏文件,可以用命令l.  ...