您好!欢迎来到源码码网

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

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

在之前的教程中介绍过拍照程序,是通过 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)
推荐阅读
  • 大型后台管理系统,用户登录状态该如何保存?
  • 大型后台管理系统,用户登录状态该如何保存?
  • 大型后台管理系统的用户登录状态保存需要综合考虑安全性、用户体验和系统架构。以下是企业级的完整方案:1.多层级存储策略class AuthManager {    constructor() {        this.storage = { &n
  • 源码教程
  • 来源:源码码网
  • 编辑:源码码网
  • 时间:2025-11-06 12:16
  • 阅读:350
  • 源码交易平台的支付困局与解决方案:如何通过专业支付系统提升交易效率
  • 源码交易平台的支付困局与解决方案:如何通过专业支付系统提升交易效率
  • 在数字经济蓬勃发展的今天,源码交易市场已成为互联网创业者和开发商的重要资源池。从电商系统源码到社交应用框架,从小程序解决方案到企业级管理系统,越来越多的开发者、初创企业和传统商家通过源码交易平台快速获取技术资产,实现商业目标的加速。源码交易市场的繁荣反映了数字化转型的迫切需求——企业需要快速迭代,开发者需要快速变现,用户需要快速启动。然而,在这个高速发展的市场中,一个长期被忽视但至关重要的问题浮现出来:支付系统的效率与安全性已成为制约交
  • 行业资讯
  • 来源:源码码网
  • 编辑:源码码网
  • 时间:2025-10-23 15:16
  • 阅读:298
  • Spring Boot 工程中 maven-surefire-plugin 测试执行失败及解决方法
  • Spring Boot 工程中 maven-surefire-plugin 测试执行失败及解决方法
  • 在SpringBoot工程编译时遇到maven-surefire-plugin的测试执行失败错误(Failedtoexecutegoalorg.apache.maven.plugins:maven-surefire-plugin:3.5.3:test),通常与测试环节相关。以下是常见原因及解决方法:1.测试用例执行失败• 原因:最常见的是测试用例(*Test.java)运行时抛出异常(如断言失败、空指针等),导
  • 源码教程
  • 来源:源码码网
  • 编辑:源码码网
  • 时间:2025-10-13 10:57
  • 阅读:363
  • WeMark - 微信小程序图片水印
  • WeMark - 微信小程序图片水印
  • 一个纯前端的微信小程序图片水印工具。支持文字/图片水印、单个与全屏两种模式,透明度与角度调节、单个水印位置X/Y控制,预览与对比模态、历史记录(100条)等功能。
  • 源码教程
  • 来源:源码码用户
  • 编辑:yg
  • 时间:2025-09-22 16:09
  • 阅读:287
联系客服
源码代售 源码咨询 素材咨询 联系客服
029-84538663
手机版

扫一扫进手机版
返回顶部