首页 > 系统 > Android > 正文

Android 开发随手笔记之使用摄像头拍照

2019-10-24 20:33:22
字体:大 中 小
来源:转载
供稿:网友

在Android中,使用摄像头拍照一般有两种方法, 一种是调用系统自带的Camera,另一种是自己写一个摄像的界面,本篇文章给大家介绍android开发随手笔记之使用摄像头拍照,感兴趣的朋友一起学习吧

在Android中,使用摄像头拍照一般有两种方法, 一种是调用系统自带的Camera,另一种是自己写一个摄像的界面。

我们要添加如下权限:

 

 
  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
  2. <uses-permission android:name="android.permission.CAMERA"/> 

1、调用系统Camera

调用系统自带的Camera主要的步骤为:

(1)构造图片存储的路径名

(2)使用Intent启动Camera Activity

(3)将拍摄的图片写入到文件

(4)将图片显示在MainActivity中

首先,构造图片名:

 

 
  1. File filePath = new File(Environment.getExternalStorageDirectory(), "myCamera"); 
  2. if(!filePath.exists()){ 
  3. filePath.mkdirs(); 
  4. } 
  5. fileName = new File(filePath, System.currentTimeMillis() + ".jpg"); 
  6. try{ 
  7. if(!fileName.exists()){ 
  8. fileName.createNewFile(); 
  9. } 
  10. }catch (Exception e){ 
  11. e.printStackTrace(); 
  12. } 

然后,启动Camera Activity:

 

 
  1. // intent用来启动系统自带的Camera 
  2. Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
  3. // 将系统Camera的拍摄结果写入到文件 
  4. intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(fileName)); 
  5. // 启动intent对应的Activity,返回默认消息 
  6. startActivityForResult(intent, Activity.DEFAULT_KEYS_DIALER); 

最后,将图片显示在MainActivity内。这时,我们通过重载onActivityResult()方法来获取Camera返回的消息。

 

 
  1. @Override 
  2. protected void onActivityResult(int requestCode, int resultCode, Intent data){ 
  3. if(requestCode == Activity.DEFAULT_KEYS_DIALER){ 
  4. // MainActivity接收Camera返回的消息,然后将已经写入的图片显示在ImageView内 
  5. imageView.setImageURI(Uri.fromFile(fileName)); 
  6. } 
  7. } 

完整代码为:

 

 
  1. import android.app.Activity; 
  2. import android.content.Intent; 
  3. import android.net.Uri; 
  4. import android.os.Bundle; 
  5. import android.os.Environment; 
  6. import android.provider.MediaStore; 
  7. import android.util.Log; 
  8. import android.view.View; 
  9. import android.widget.Button; 
  10. import android.widget.ImageView; 
  11. import java.io.File; 
  12. public class MainActivity extends Activity { 
  13. private File fileName = null; 
  14. private Button button; 
  15. private ImageView imageView; 
  16. @Override 
  17. protected void onCreate(Bundle savedInstanceState) { 
  18. super.onCreate(savedInstanceState); 
  19. setContentView(R.layout.activity_main); 
  20. button = (Button)findViewById(R.id.button); 
  21. imageView = (ImageView)findViewById(R.id.imageView); 
  22. button.setOnClickListener(new View.OnClickListener() { 
  23. @Override 
  24. public void onClick(View v) { 
  25. File filePath = new File(Environment.getExternalStorageDirectory(), "myCamera"); 
  26. if(!filePath.exists()){ 
  27. filePath.mkdirs(); 
  28. } 
  29. fileName = new File(filePath, System.currentTimeMillis() + ".jpg"); 
  30. try{ 
  31. if(!fileName.exists()){ 
  32. fileName.createNewFile(); 
  33. } 
  34. }catch (Exception e){ 
  35. e.printStackTrace(); 
  36. } 
  37. // intent用来启动系统自带的Camera 
  38. Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
  39. // 将系统Camera的拍摄结果写入到文件 
  40. intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(fileName)); 
  41. // 启动intent对应的Activity,返回默认消息 
  42. startActivityForResult(intent, Activity.DEFAULT_KEYS_DIALER); 
  43. } 
  44. }); 
  45. } 
  46. @Override 
  47. protected void onActivityResult(int requestCode, int resultCode, Intent data){ 
  48. if(requestCode == Activity.DEFAULT_KEYS_DIALER){ 
  49. // MainActivity接收Camera返回的消息,然后将已经写入的图片显示在ImageView内 
  50. imageView.setImageURI(Uri.fromFile(fileName)); 
  51. } 
  52. } 
  53. } 

2、自己写一个摄像界面

自己写摄像的界面,主要应用了SurfaceView来显示摄像机的画面。然后通过一个Button来保存当前的画面。

同样的,我们需要添加camera和SDCard权限:

 

 
  1. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
  2. <uses-permission android:name="android.permission.CAMERA"/> 

首先,我们初始化这个SurfaceView,为这个SurfaceView添加一个对应的Callback即可:

 

 
  1. private SurfaceView surfaceView; 
  2. private SurfaceHolder.Callback callback; 
  3. surfaceView = (SurfaceView)findViewById(R.id.surfaceView); 
  4. callback = new SurfaceHolder.Callback(){ 
  5. @Override 
  6. public void surfaceCreated(SurfaceHolder holder) { 
  7. startCamera(); // 用于启动摄像头 
  8. } 
  9. @Override 
  10. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
  11. } 
  12. @Override 
  13. public void surfaceDestroyed(SurfaceHolder holder) { 
  14. stopCamera(); // 用于关闭摄像头 
  15. } 
  16. }; 
  17. surfaceView.getHolder().addCallback(callback); // 将Callback绑定到SurfaceView 

在启动摄像头的时候,首先打开摄像头连接,然后将其图像输出到SurfaceView上,然后启动摄像头预览即可在SurfaceView上显示摄像头的画面,这里的画面和实际画面相差有90度,所以我们需要将图像旋转90度之后才可以和拍摄的物体方向一致。

在关闭摄像头时,只要停止预览,然后释放摄像头资源即可。

 

 
  1. public void startCamera(){ 
  2. camera = Camera.open(); 
  3. try { 
  4. camera.setPreviewDisplay(surfaceView.getHolder()); 
  5. camera.setDisplayOrientation(90); 
  6. camera.startPreview(); 
  7. } catch (IOException e) { 
  8. e.printStackTrace(); 
  9. } 
  10. } 
  11. public void stopCamera(){ 
  12. camera.stopPreview(); 
  13. camera.release(); 
  14. camera = null; 
  15. } 

最后,是将拍摄到的图片保存到SDCard,我们单击Button来拍摄图片,调用Camera.takePicture()方法,其原型为:

 

 
  1. /** 
  2. * Equivalent to takePicture(shutter, raw, null, jpeg). 
  3. * 
  4. * @see #takePicture(ShutterCallback, PictureCallback, PictureCallback, PictureCallback) 
  5. */ 
  6. public final void takePicture(ShutterCallback shutter, PictureCallback raw, 
  7. PictureCallback jpeg) { 
  8. takePicture(shutter, raw, null, jpeg); 
  9. } 

其中,shutter为按快门瞬间的回调,就是说按快门瞬间会调用ShutterCallback.onShutter()方法。raw是未压缩的图像的回调,即处理图像原始数据的时候会调用PictureCallback.onPictureTaken()方法。jpeg为处理JPEG图片时候的回调,即我们需要将图像数据按照jpg格式保存的时候会调用这个方法,PictureCallback.onPIctureTaken()。这里我们就调用了这个方法,从而将jpg图片存储到SDCard上。

 

 
  1. button.setOnClickListener(new View.OnClickListener() { 
  2. @Override 
  3. public void onClick(View v) { 
  4. camera.takePicture(null, null, new Camera.PictureCallback() { 
  5. @Override 
  6. public void onPictureTaken(byte[] data, Camera camera) { 
  7. try { 
  8. File filePath = new File(Environment.getExternalStorageDirectory(), "myCamera"); 
  9. if(!filePath.exists()) { 
  10. filePath.mkdirs(); 
  11. } 
  12. File fileName = new File(filePath, System.currentTimeMillis() + ".jpg"); 
  13. fileName.createNewFile(); 
  14. FileOutputStream fos = new FileOutputStream(fileName); 
  15. fos.write(data); 
  16. fos.flush(); 
  17. fos.close(); 
  18. } catch (IOException e) { 
  19. e.printStackTrace(); 
  20. } 
  21. } 
  22. }); 
  23. } 
  24. }); 

这样,我们便实现了用SurfaceView预览摄像头画面,点击Button将当前预览保存到SDCard中。

完整代码如下:

 

 
  1. import android.app.Activity; 
  2. import android.hardware.Camera; 
  3. import android.os.Bundle; 
  4. import android.os.Environment; 
  5. import android.view.SurfaceHolder; 
  6. import android.view.SurfaceView; 
  7. import android.view.View; 
  8. import android.widget.Button; 
  9. import java.io.File; 
  10. import java.io.FileOutputStream; 
  11. import java.io.IOException; 
  12. public class MainActivity extends Activity { 
  13. private Camera camera; 
  14. private Button button; 
  15. private SurfaceView surfaceView; 
  16. private SurfaceHolder.Callback callback; 
  17. @Override 
  18. protected void onCreate(Bundle savedInstanceState) { 
  19. super.onCreate(savedInstanceState); 
  20. setContentView(R.layout.activity_main); 
  21. button = (Button)findViewById(R.id.button); 
  22. surfaceView = (SurfaceView)findViewById(R.id.surfaceView); 
  23. callback = new SurfaceHolder.Callback(){ 
  24. @Override 
  25. public void surfaceCreated(SurfaceHolder holder) { 
  26. startCamera(); 
  27. } 
  28. @Override 
  29. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
  30. } 
  31. @Override 
  32. public void surfaceDestroyed(SurfaceHolder holder) { 
  33. stopCamera(); 
  34. } 
  35. }; 
  36. surfaceView.getHolder().addCallback(callback); 
  37. button.setOnClickListener(new View.OnClickListener() { 
  38. @Override 
  39. public void onClick(View v) { 
  40. camera.takePicture(null, null, new Camera.PictureCallback() { 
  41. @Override 
  42. public void onPictureTaken(byte[] data, Camera camera) { 
  43. try { 
  44. File filePath = new File(Environment.getExternalStorageDirectory(), "myCamera"); 
  45. if(!filePath.exists()) { 
  46. filePath.mkdirs(); 
  47. } 
  48. File fileName = new File(filePath, System.currentTimeMillis() + ".jpg"); 
  49. fileName.createNewFile(); 
  50. FileOutputStream fos = new FileOutputStream(fileName); 
  51. fos.write(data); 
  52. fos.flush(); 
  53. fos.close(); 
  54. } catch (IOException e) { 
  55. e.printStackTrace(); 
  56. } 
  57. } 
  58. }); 
  59. } 
  60. }); 
  61. } 
  62. public void startCamera(){ 
  63. camera = Camera.open(); 
  64. try { 
  65. camera.setPreviewDisplay(surfaceView.getHolder()); 
  66. camera.setDisplayOrientation(90); 
  67. camera.startPreview(); 
  68. } catch (IOException e) { 
  69. e.printStackTrace(); 
  70. } 
  71. } 
  72. public void stopCamera(){ 
  73. camera.stopPreview(); 
  74. camera.release(); 
  75. camera = null; 
  76. } 
  77. } 

以上所述是本文给大家介绍的关于Android 开发随手笔记之使用摄像头拍照的全部内容,希望大家喜欢。


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表