本讲内容: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. web api 获取传过来的Json

    public async void PostOrder(HttpRequestMessage request) { String responseBodyAsText = await request. ...

  2. unity3D中 material中tiling和offset属性解释

    贴图有可能是多行多列的一些图案组成的.当我们需要一帧,一帧的播放时候.也就是帧序列动画, 我们就需要用到tiling和offset两个属性, 默认图片的左下角为坐标圆点即:(0,0) tiling是图 ...

  3. Twitter OA prepare: Two Operations

    准备T家OA,网上看的面经 最直接的方法,从target降到1,如果是奇数就减一,偶数就除2 public static void main(String[] args) { int a = shor ...

  4. 004-ubuntu安装配置SSH服务

    一.ssh安装. 1.# sudo apt-get -y install openssh-server. 2.在/etc/ssh/sshd_config文件中添加一句:PermitRootLogin ...

  5. animation-fill-mode

    animation-fill-mode: none:默认值.不设置对象动画之外的状态 forwards:结束后保持动画结束时的状态,但当animation-direction为0,则动画不执行,持续保 ...

  6. php随笔10-thinkphp 3.1.3 模板继承 布局

    8.25 模板继承 模 板继承是3.1.2版本添加的一项更加灵活的模板布局方式,模板继承不同于模板布局,甚至来说,应该在模板布局的上层.模板继承其实并不难理解,就好比类 的继承一样,模板也可以定义一个 ...

  7. JavaScript 实现省市二级联动

    JavaScript 实现省市二级联动 版权声明:未经授权,严禁转载! 案例代码 <style> .hide { display: none; } </style> <s ...

  8. php 设置模式 单元素模式(单例模式或单件模式)

    单元素模式: 某些应用程序资源是独占的,因为有且只有一个此类型的资源.应用程序每次包含且仅包含一个对象,那么这个对象就是一个单元素.指的是在应用程序的范围内只对指定的类创建一个实例.通常该模式中包含一 ...

  9. VC++开机自动启动程序的几种方法 (转载)

    转载:http://blog.csdn.net/zhazhiqiang/article/details/51909703 很多监控软件要求软件能够在系统重新启动后不用用户去点击图标启动项目,而是直接能 ...

  10. vim常用的配置

    .vimrc配置 syntax enable syntax on set relativenumber set autoindent set tabstop=4 set expandtab " ...