源码教程 2025年06月7日
0 收藏 0 点赞 451 浏览 7874 个字
摘要 :

在之前的教程中介绍过拍照程序,是通过 Intent调用 Android 系统提供的照相机程序实现的。Android SDK 提供了直接操作移动设备摄像头的 android.hardware.Came……

在之前的教程中介绍过拍照程序,是通过 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 所示。

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

图 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();

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/1013.html

管理员

相关推荐
2025-07-05

对于一些使用WordPress进行外贸建站的商家来说,大部分人会通过在WordPress中添加JS代码和CSS样式表…

700
2025-07-05

当商家遇到WordPress独立站改版或者域名到期等问题时,不免会涉及到WordPress域名的更改,那么这一…

714
2025-07-05

用户在使用WooCommerce进行跨境电商独立站搭建工作时,有可能会借助WooCommerce短代码实现更加醒目…

305
2025-07-05

随着外贸建站行业的不断深入发展,WordPress的多语言功能也显得越来越重要,一个具有多语言的独立站…

1,038
2025-07-05

WooCommerce作为WordPress外贸建站生态的一部分,WooCommerce运费设置是商家在建站过程中不可忽视的…

834
2025-07-05

在外贸建站的过程中,有些商家会选择使用WordPress幻灯片为网站页面增加一定的动感和可观性,进而提…

721
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号