您好!欢迎来到源码码网

Android Camera相机以及相机程序开发实例

  • 源码教程
  • 来源:源码码网
  • 编辑:admin
  • 时间:2021-01-14 20:32
  • 阅读:751

在之前的教程中介绍过拍照程序,是通过 Intent调用 Android 系统提供的照相机程序实现的。

Android SDK 提供了直接操作移动设备摄像头的 android.hardware.Camera 类,通过该类的相关 API,可以直接操作 Android 手机中的摄像头,以方便开发自己的拍照程序。

使用 Camera 类访问移动设备的摄像头,需要在应用程序的 AndroidManifest.xml 文件中做以下声明:

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />


使用 Camera 类进行拍照的步骤如下:

1)使用 Camera.open() 方法获取 Camera 对象实例。

2)使用 Camera.getParameters() 方法获取当前相机的相关设置。

3)根据需要使用 Camera.setParameters() 方法设置相机的相关参数。

4)根据需要使用 Camera.setDisplayOrientation() 设置相机正向。

5)使用 Camera.setPreviewDisplay() 方法为相机设置一个用于显示相机图像的 Surface。

6)使用 Camera.startPreview() 启动预览。

7)使用 Camera.takePicture() 方法进行拍照。

8)进行拍照后,预览视图会停止。使用 Camera.startPreview() 方法重新启动预览。

9)使用 Camera.stopPreview() 停止预览。

10)使用 Camera.release() 方法释放相机对象。应该在应用程序的 onPause() 方法中释放相机对象,在 onResume() 方法中重新打开相机对象。

实例 MyCameraDemo 演示了使用 Camera 类进行拍照的过程,该应用程序的运行效果如图 1 所示。

MyCameraDemo运行结果

图 1  MyCameraDemo运行结果

该视图所使用布局文件 main.xml 的代码如下:


  1. <?xml version="1.0" encoding="utf-8"?>

  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

  3. android:layout_width="fill_parent"

  4. android:layout_height="fill_parent"

  5. android:orientation="vertical">


  6. <TextView

  7. android:layout_width="fill_parent"

  8. android:layout_height="wrap_content"

  9. android:text="@string/hello" />


  10. <SurfaceView

  11. android:id="@+id/surfaceView1"

  12. android:layout_width="fill_parent"

  13. android:layout_height="wrap_content"

  14. android:layout_weight="0.58" />


  15. <LinearLayout

  16. android:id="@+id/linearLayout1"

  17. android:layout_width="match_parent"

  18. android:layout_height="wrap_content"

  19. android:gravity="center">


  20. <Button

  21. android:id="@+id/button1"

  22. android:layout_width="wrap_content"

  23. android:layout_height="wrap_content"

  24. android:text="@string/opBtn" />


  25. <Button

  26. android:id="@+id/button2"

  27. android:layout_width="wrap_content"

  28. android:layout_height="wrap_content"

  29. android:text="@string/play" />


  30. <Button

  31. android:id="@+id/button3"

  32. android:layout_width="wrap_content"

  33. android:layout_height="wrap_content"

  34. android:text="@string/cloBtn" />



  35. </LinearLayout>



  36. </LinearLayout>

实例 MyCameraDemo 使用到的资源文件 string.xml 的代码如下:

  1. <resources>

  2. <string name="hello">使用Android.hardware.Camera</string>

  3. <string name="app_name">MyCameraDemo</string>

  4. <string name="opBtn">打开摄像头</string>

  5. <string name="play">拍摄</string>

  6. <string name="cloBtn">关闭摄像头</string>

  7. </resources>

由于实例 MyCameraDemo 中涉及将拍摄的照片保存到 SD 卡中的功能,因此需要在该工程的 AndroidManifest.xml 文件中声明相应权限。该文件内容如下:


  1. <?xml version="1.0" encoding="utf-8"?>

  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"

  3. package="introduction.android.mycamerademo"

  4. android:versionCode="1"

  5. android:versionName="1.0">


  6. <uses-sdk android:minSdkVersion="14" />

  7. <uses-feature android:name="android.hardware.camera" />


  8. <uses-permission android:name="android.permission.CAMERA" />

  9. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


  10. <application

  11. android:allowBackup="true"

  12. android:icon="@mipmap/ic_launcher"

  13. android:label="@string/app_name"

  14. android:roundIcon="@mipmap/ic_launcher_round"

  15. android:supportsRtl="true"

  16. android:theme="@style/AppTheme">

  17. <activity android:name=".MainActivity">

  18. <intent-filter>

  19. <action android:name="android.intent.action.MAIN" />


  20. <category android:name="android.intent.category.LAUNCHER" />

  21. </intent-filter>

  22. </activity>

  23. </application>


  24. </manifest>

实例 MyCameraDemo 的主 Activity 为 MainActivity,其代码如下:


  1. package introduction.android.mycamerademo;


  2. import java.io.BufferedOutputStream;

  3. import java.io.File;


  4. import java.io.FileNotFoundException;

  5. import java.io.FileOutputStream;

  6. import java.io.IOException;


  7. import android.app.Activity;

  8. import android.graphics.Bitmap;

  9. import android.graphics.BitmapFactory;

  10. import android.graphics.PixelFormat;

  11. import android.hardware.Camera;

  12. import android.hardware.Camera.Parameters;

  13. import android.hardware.Camera.PictureCallback;

  14. import android.os.Bundle;

  15. import android.util.Log;

  16. import android.view.SurfaceHolder;

  17. import android.view.SurfaceView;

  18. import android.view.View;

  19. import android.view.View.OnClickListener;

  20. import android.widget.Button;


  21. public class MainActivity extends Activity {

  22. private Button opbtn;

  23. private Button playbtn;

  24. private Button clobtn;

  25. private SurfaceView surfaceView;

  26. private SurfaceHolder surfaceHolder;

  27. private Camera camera;

  28. private int previewWidth = 320;

  29. private int previewHeight = 240;


  30. protected String filepath = "/sdcard/mypicture.jpg";


  31. /**

  32.     * Called when the activity is first created.

  33.     */

  34. @Override

  35. public void onCreate(Bundle savedInstanceState) {

  36. super.onCreate(savedInstanceState);

  37. setContentView(R.layout.activity_main);

  38. opbtn = (Button) this.findViewById(R.id.button1);

  39. playbtn = (Button) this.findViewById(R.id.button2);

  40. clobtn = (Button) this.findViewById(R.id.button3);

  41. surfaceView = (SurfaceView) this.findViewById(R.id.surfaceView1);

  42. surfaceHolder = surfaceView.getHolder();

  43. surfaceHolder.addCallback(new SurfaceHolder.Callback() {


  44. @Override

  45. public void surfaceDestroyed(SurfaceHolder holder) {

  46. // TODO Auto-generated method stub

  47. Log.i("camera", "surface destroyed.");

  48. }


  49. @Override

  50. public void surfaceCreated(SurfaceHolder holder) {

  51. // TODO Auto-generated method stub

  52. Log.i("camera", "surface destroyed");

  53. }


  54. @Override

  55. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

  56. // TODO Auto-generated method stub

  57. Log.i("camera", "surface changed.");

  58. }

  59. });

  60. opbtn.setOnClickListener(new OnClickListener() {

  61. //开启摄像头

  62. @Override

  63. public void onClick(View argO) {

  64. // TODO Auto-generated method stub

  65. openCamera();

  66. }

  67. });

  68. playbtn.setOnClickListener(new OnClickListener() {

  69. //拍照

  70. @Override

  71. public void onClick(View v) {

  72. // TODO Auto-generated method stub

  73. takePicture();

  74. }

  75. });

  76. clobtn.setOnClickListener(new OnClickListener() {

  77. //关闭摄像头

  78. @Override

  79. public void onClick(View v) {

  80. // TODO Auto-generated method stub

  81. closeCamera();

  82. }

  83. });

  84. }


  85. protected void closeCamera() {

  86. // TODO Auto-generated method stub

  87. camera.stopPreview();

  88. camera.release();

  89. camera = null;

  90. }


  91. protected void takePicture() {

  92. // TODO Auto-generated method stub

  93. if (checkSDCard()) {

  94. camera.takePicture(null, null, jpeg);

  95. try {

  96. Thread.sleep(1000);

  97. } catch (InterruptedException e) {

  98. // TODO Auto-generated catch block

  99. e.printStackTrace();

  100. }

  101. camera.startPreview();

  102. } else {

  103. Log.e("camera", "SD CARD not exist.");

  104. return;

  105. }

  106. }


  107. private void openCamera() {

  108. // TODO Auto-generated method stub

  109. try {

  110. camera = Camera.open(); // attempt to get a Camera instance

  111. } catch (Exception e) {

  112. // Camera is not available (in use or does not exist)

  113. Log.e("camera", "open camera error!");

  114. e.printStackTrace();

  115. return;

  116. }

  117. Parameters params = camera.getParameters();

  118. params.setPreviewSize(previewWidth, previewHeight);

  119. params.setPictureFormat(PixelFormat.JPEG);

  120. params.setPictureSize(previewWidth, previewHeight);

  121. camera.setParameters(params);

  122. try {

  123. camera.setPreviewDisplay(surfaceHolder);

  124. } catch (IOException e) {

  125. // TODO Auto-generated catch block

  126. Log.e("camera", "preview failed.");

  127. e.printStackTrace();

  128. }

  129. camera.startPreview();

  130. }


  131. private PictureCallback jpeg = new PictureCallback() {

  132. @Override

  133. public void onPictureTaken(byte[] data, Camera camera) {

  134. // TODO Auto-generated method stub

  135. Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

  136. File pictureFile = new File(filepath);

  137. if (pictureFile == null) {

  138. Log.d("camera",

  139. "Error creating media file, check storage permissions");

  140. return;

  141. }

  142. try {

  143. //将拍摄的照片写入SD卡中

  144. FileOutputStream fos = new FileOutputStream(pictureFile);

  145. BufferedOutputStream bos = new BufferedOutputStream(fos);

  146. bitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);

  147. bos.flush();

  148. bos.close();

  149. fos.close();

  150. Log.i("camera", "jpg file saved.");

  151. } catch (FileNotFoundException e) {

  152. Log.d("camera", "File not found: " + e.getMessage());

  153. } catch (IOException e) {

  154. Log.d("camera", "Error accessing file: " + e.getMessage());

  155. }

  156. }

  157. };


  158. private boolean checkSDCard() {

  159. // 判断SD存储卡是否存在

  160. if (android.os.Environment.getExternalStorageState().equals

  161. (android.os.Environment.MEDIA_MOUNTED)) {

  162. return true;

  163. } else {

  164. return false;

  165. }

  166. }

  167. }


其中,openCamera() 方法用于打开当前设备的相机,并通过:

  1. Parameters params=camera.getParameters();

  2. params.setPreviewSize(previewWidth, previewHeight);

  3. params.setPictureFormat(PixelFormat.JPEG);

  4. params.setPictureSize(previewWidth, previewHeight);

  5. camera.setParameters(params);

设置相机的相关参数,以用于照片拍摄。

通过以下代码:

surfaceView=(SurfaceView)this.findViewById(R.id.surfaceView1);
surfaceHolder=surfaceView.getHolder();
camera.setPreviewDisplay(surfaceHolder);

将布局中的 SurfaceView 组件设置为相机的预览窗口。

由于在拍摄照片后,预览视图会自动停止预览而显示拍摄的照片,因此在本例中人为将照片显示时间设定为 1s,然后重新启动预览。相关代码如下:

  1. camera.takePicture(null, null, jpeg);

  2. try {

  3. Thread.sleep(1000);

  4. } catch (InterruptedException e) {

  5. // TODO Auto-generated catch block

  6. e.printStackTrace();

  7. }

  8. camera.startPreview();


特别声明:
1、如无特殊说明,内容均为本站原创发布,转载请注明出处;
2、部分转载文章已注明出处,转载目的为学习和交流,如有侵犯,请联系客服删除;
3、编辑非《源码码网》的文章均由用户编辑发布,不代表本站立场,如涉及侵犯,请联系删除;
全部评论(0)
推荐阅读
  • 陀螺匠OA办公系统源码 PHP + Vue 前后端分离 完整可商用
  • 陀螺匠OA办公系统源码 PHP + Vue 前后端分离 完整可商用
  • 项目介绍《陀螺匠》是一套采用Laravel9框架结合Swoole高性能框架与Vue.js前端技术栈构建的AI+低代码双引擎智能办公系统。陀螺匠深度融合了AI智能体以及低代码开发平台,系统简约,易于功能扩展,方便二次开发。旨在为企业提供一站式、数智化转型的全方位解决方案,助力企业高效运营与智能决策。源码说明源码说明:项目代码100%开源,基于AGPL-3.0,支持免费商用!技术栈:系统基于Laravel9+Swoole+Vue.
  • 软件教程
  • 来源:CRMEB
  • 编辑:CRMEB
  • 时间:2026-03-27 15:33
  • 阅读:393
  • open claw最近很火,如何理性看待?
  • open claw最近很火,如何理性看待?
  • openclaw是2026年初科技圈最火爆的现象级话题。它不仅仅是又一个AI产品,更被百川智能的王小川誉为与ChatGPT诞生同等重要的里程碑——标志着AI从”只会说”的对话者,进化到了”能够做”的行动者。对于这股全民”养虾”热潮,我的观察是:它代表了一次人机关系的革命性跃迁,但同时也是一场充满风险与泡沫的狂欢,其真正的价值需要在喧嚣褪去、安全与成本的挑战被克服后才能显现。下
  • 行业资讯
  • 来源:源码码网
  • 编辑:源码码网
  • 时间:2026-03-17 11:06
  • 阅读:432
  • 原生小程序和封装的小程序有什么区别
  • 原生小程序和封装的小程序有什么区别
  • 原生小程序和封装的小程序是两种不同的开发模式,主要区别在于开发方式、性能表现、代码维护以及跨平台能力。为了让你更清晰地理解,我们可以把“原生”比作用钢筋水泥直接盖楼,而“封装”则是用预制板或套件来组装楼。以下是详细的对比分析:1.定义与本质原生小程序:定义: 直接使用微信官方提供的开发工具、语法和API进行开发。语言: 使用微信自己定义的一套技术栈(WXML(微信标记语言)做结构、WXSS(微信样式表)做样式、JS
  • 行业资讯
  • 来源:源码码网
  • 编辑:源码码网
  • 时间:2026-03-06 11:54
  • 阅读:666
  • 基于NetCore(Razor Page)开发的Cms建站系统MIT协议
  • 基于NetCore(Razor Page)开发的Cms建站系统MIT协议
  • FytSoaCms一款基于NetCore2.2/3.1(RazorPage)功能强大的Cms建站系统,支持前后端分离。简介:模块化:全新的架构和模块化的开发机制,便于灵活扩展和二次开发。模型/栏目/分类信息体系:通过栏目和模型绑定,以及不同的模型类型,不同栏目可以实现差异化的功能,轻松实现诸如资讯、下载、讨论和图片等功能。通过分类信息和栏目绑定,可以自动建立索引表,轻松实现复杂的信息检索。FytSoa是一套基于NetCore+SqlS
  • 开发工具
  • 来源:gitee
  • 编辑:源码码网
  • 时间:2026-01-24 22:21
  • 阅读:592
  • 基于JAVA开发的企业级平台微信公众号管理系统SmartWx
  • 基于JAVA开发的企业级平台微信公众号管理系统SmartWx
  • SmartWx微信公众号管理系统是一个完整的微信公众号web操作版,直接编译即可运行。让用户不再用关心微信的底层接口,直接使用页面进行操作,简单方便。包括服务器绑定、文本管理、图文管理、菜单管理、粉丝管理、群发消息等。技术框架开发语言:JAVA数据库:MYSQLJAVA开发框架:SpringMVC+Spring+Mybatis缓存框架:j2cache前端开发框架:Layui+JQuery+html前台模板引擎:art-templat
  • 源码教程
  • 来源:gitee
  • 编辑:源码码网
  • 时间:2026-01-24 21:53
  • 阅读:601
联系客服
源码代售 源码咨询 技术开发 联系客服
029-84538663
手机版

扫一扫进手机版
返回顶部