首页 > 系统 > 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. fileName = new File(filePath, System.currentTimeMillis() + ".jpg"); 
  5. try
  6. if(!fileName.exists()){ 
  7. fileName.createNewFile(); 
  8. }catch (Exception e){ 
  9. e.printStackTrace(); 

然后,启动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)); 

完整代码为:

 

 
  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. fileName = new File(filePath, System.currentTimeMillis() + ".jpg"); 
  29. try
  30. if(!fileName.exists()){ 
  31. fileName.createNewFile(); 
  32. }catch (Exception e){ 
  33. e.printStackTrace(); 
  34. // intent用来启动系统自带的Camera 
  35. Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
  36. // 将系统Camera的拍摄结果写入到文件 
  37. intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(fileName)); 
  38. // 启动intent对应的Activity,返回默认消息 
  39. startActivityForResult(intent, Activity.DEFAULT_KEYS_DIALER); 
  40. }); 
  41. @Override 
  42. protected void onActivityResult(int requestCode, int resultCode, Intent data){ 
  43. if(requestCode == Activity.DEFAULT_KEYS_DIALER){ 
  44. // MainActivity接收Camera返回的消息,然后将已经写入的图片显示在ImageView内 
  45. imageView.setImageURI(Uri.fromFile(fileName)); 

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. @Override 
  9. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
  10. @Override 
  11. public void surfaceDestroyed(SurfaceHolder holder) { 
  12. stopCamera(); // 用于关闭摄像头 
  13. }; 
  14. 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. public void stopCamera(){ 
  10. camera.stopPreview(); 
  11. camera.release(); 
  12. camera = null

最后,是将拍摄到的图片保存到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); 

其中,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(nullnullnew 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. File fileName = new File(filePath, System.currentTimeMillis() + ".jpg"); 
  12. fileName.createNewFile(); 
  13. FileOutputStream fos = new FileOutputStream(fileName); 
  14. fos.write(data); 
  15. fos.flush(); 
  16. fos.close(); 
  17. catch (IOException e) { 
  18. e.printStackTrace(); 
  19. }); 
  20. }); 

这样,我们便实现了用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. @Override 
  28. public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
  29. @Override 
  30. public void surfaceDestroyed(SurfaceHolder holder) { 
  31. stopCamera(); 
  32. }; 
  33. surfaceView.getHolder().addCallback(callback); 
  34. button.setOnClickListener(new View.OnClickListener() { 
  35. @Override 
  36. public void onClick(View v) { 
  37. camera.takePicture(nullnullnew Camera.PictureCallback() { 
  38. @Override 
  39. public void onPictureTaken(byte[] data, Camera camera) { 
  40. try { 
  41. File filePath = new File(Environment.getExternalStorageDirectory(), "myCamera"); 
  42. if(!filePath.exists()) { 
  43. filePath.mkdirs(); 
  44. File fileName = new File(filePath, System.currentTimeMillis() + ".jpg"); 
  45. fileName.createNewFile(); 
  46. FileOutputStream fos = new FileOutputStream(fileName); 
  47. fos.write(data); 
  48. fos.flush(); 
  49. fos.close(); 
  50. catch (IOException e) { 
  51. e.printStackTrace(); 
  52. }); 
  53. }); 
  54. public void startCamera(){ 
  55. camera = Camera.open(); 
  56. try { 
  57. camera.setPreviewDisplay(surfaceView.getHolder()); 
  58. camera.setDisplayOrientation(90); 
  59. camera.startPreview(); 
  60. catch (IOException e) { 
  61. e.printStackTrace(); 
  62. public void stopCamera(){ 
  63. camera.stopPreview(); 
  64. camera.release(); 
  65. camera = null

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


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