在android中应用相机功能,一般有两种:一种是直接调用系统相机,一种自己写的相机。我将分别演示两种方式的使用:

第一种:是使用Intent跳转到系统相机,action为:android.media.action.STILL_IMAGE_CAMERA

关键代码:

Java代码:
01.Intent intent = new Intent(); //调用照相机

02.intent.setAction("android.media.action.STILL_IMAGE_CAMERA");

03.startActivity(intent);
复制代码 例子:CameraTest_2.java

Java代码:

01.import android.app.Activity;

02.import android.content.Intent;

03.import android.os.Bundle;

04.

05.public class CameraTest_2 extends Activity {

06./** Called when the activity is first created. */

07.@Override

08.public void onCreate(Bundle savedInstanceState) {

09.super.onCreate(savedInstanceState);

10.setContentView(R.layout.main);

11.Intent intent = new Intent(); //调用照相机

12.intent.setAction("android.media.action.STILL_IMAGE_CAMERA");

13.startActivity(intent);

14.}

15.

16.}
复制代码
想要测试的,可以直接新建一个项目,并且把主activity的代码换成上面的,然后运行,我测试了一下,上面这个代码并不需要权限,毕竟只是调用系统自带的程序。
当然网上还有一些其他相关的调用方法,只要设置对了action,那么系统就会调用系统自带的相机.

第二种:
(1)首先我们要自己创建一个照相,必须考虑用什么控件显示照相机中的预览效果,显然android已经帮我们做好了选择,那就是SurfaceView,而控制SurfaceView则需要一个surfaceHolder,他是系统提供的一个用来设置surfaceView的一个对象,而它通过surfaceView.getHolder()这个方法来获得。而Camera提供一个setPreviewDisplay(SurfaceHolder)的方法来连接.surfaceHolder,并通过他来控制surfaceView,而我们则使用android的Camera类提供了startPreview()和stopPreview()来开启和关闭预览.

关系如下:
Camera -- -->SurfaceHolder------>SurfaceView.
(2)知道怎么预览,当然也要知道怎么开启相机.Camera.open()这是个静态方法,如果相机没有别人用着,则会返回一个 相机引用,如果被人用着,则会抛出异常。很奇怪的是,这个方法,不能随便放,如放在构造方法或者onCreate()方法中,都会照成没有预览效果.
(3)SurfaceHolder.Callback,这是个holder用来显示surfaceView 数据的接口,他分别必须实现3个方法
surfaceCreated()这个方法是surface 被创建后调用的
surfaceChanged()这个方法是当surfaceView发生改变后调用的
surfaceDestroyed()这个是当surfaceView销毁时调用的.
surfaceHolde通过addCallBack()方法将响应的接口绑定到他身上.
surfaceHolder还必须设定一个setType()方法,查看api的时候,发现这个方法已经过时,但是没有写,又会报错。。各种奇怪。
(4)我用以上知识写了一个MySurfaceView类,他继承于SurfaceView,并在里面实现了照相机的预览功能.这个我觉得最简单的照相机预览代码:

MySurfaceView.java

Java代码:

01.import java.io.IOException;

02.import android.content.Context;

03.import android.graphics.PixelFormat;

04.import android.hardware.Camera;

05.import android.util.Log;

06.import android.view.SurfaceHolder;

07.import android.view.SurfaceView;

08.

09.public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{

10.SurfaceHolder holder;

11.Camera myCamera;

12.

13.public MySurfaceView(Context context) {

14.super(context);

15.holder = getHolder();//获得surfaceHolder引用

16.holder.addCallback(this);

17.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置类型

18.}

19.

20.@Override

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

22.myCamera.startPreview();

23.}

24.@Override

25.public void surfaceCreated(SurfaceHolder holder) {

26.// TODO Auto-generated method stub

27.if(myCamera == null) {

28.myCamera = Camera.open();//开启相机,不能放在构造函数中,不然不会显示画面.

29.try {

30.myCamera.setPreviewDisplay(holder);

31.} catch (IOException e) {

32.// TODO Auto-generated catch block

33.e.printStackTrace();

34.}

35.}

36.}

37.

38.@Override

39.public void surfaceDestroyed(SurfaceHolder holder) {

40.// TODO Auto-generated method stub

41.myCamera.stopPreview();//停止预览

42.myCamera.release();//释放相机资源

43.myCamera = null;

44.Log.d("ddd", "4");

45.}

46.}
复制代码
CameraTest_3.java

Java代码:

01.import android.app.Activity;

02.import android.os.Bundle;

03.import android.view.View;

04.import android.view.View.OnClickListener;

05.

06.public class CameraTest_3 extends Activity {

07./** Called when the activity is first created. */

08.MySurfaceView mySurface;

09.@Override

10.public void onCreate(Bundle savedInstanceState) {

11.super.onCreate(savedInstanceState);

12.mySurface = new MySurfaceView(this);

13.setContentView(mySurface);

14.}

15.

16.}


而且必须给应用添加权限: <uses-permission android:name="android.permission.CAMERA"></uses-permission>
(5)能够预览了,接下来就是拍照了,拍照用到了一个camera.tackPiture()这个方法,这个方法,有三个参数分别是ShutterCallBack shutter,PictureCallBack raw,PictureCallBack jpeg.

下面是对他们的实现

Java代码:

01.private ShutterCallback shutter = new ShutterCallback() {

02.@Override

03.public void onShutter() {

04.// TODO Auto-generated method stub

05.Log.d("ddd", "shutter");

06.}

07.};

08.

09.private PictureCallback raw = new PictureCallback() {

10.@Override

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

12.// TODO Auto-generated method stub

13.Log.d("ddd", "raw");

14.}

15.};

16.

17.

18.private PictureCallback jpeg = new PictureCallback() {

19.@Override

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

21.// TODO Auto-generated method stub

22.Log.d("ddd","jpeg");

23.}

24.};
复制代码
当开始拍照时,会依次调用shutter的onShutter()方法,raw的onPictureTaken方法,jpeg的onPictureTaken方法.三个参数的作用是shutter--拍照瞬间调用,raw--获得没有压缩过的图片数据,jpeg---返回jpeg的图片数据
当你不需要对照片进行处理,可以直接用null代替.
注意,当调用camera.takePiture方法后,camera关闭了预览,这时需要调用startPreview()来重新开启预览。


我用以上知识,加到上面的那个例子,就形成了下面的代码:

MySurfaceView.java

Java代码:

01.package eoe.wjh.camera;

02.

03.import java.io.IOException;

04.import android.content.Context;

05.import android.graphics.PixelFormat;

06.import android.hardware.Camera;

07.import android.hardware.Camera.PictureCallback;

08.import android.hardware.Camera.ShutterCallback;

09.import android.util.Log;

10.import android.view.SurfaceHolder;

11.import android.view.SurfaceView;

12.

13.

14.public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{

15.SurfaceHolder holder;

16.Camera myCamera;

17.private ShutterCallback shutter = new ShutterCallback() {

18.@Override

19.public void onShutter() {

20.// TODO Auto-generated method stub

21.Log.d("ddd", "shutter");

22.}

23.};

24.

25.private PictureCallback raw = new PictureCallback() {

26.@Override

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

28.// TODO Auto-generated method stub

29.Log.d("ddd", "raw");

30.}

31.};

32.private PictureCallback jpeg = new PictureCallback() {

33.@Override

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

35.// TODO Auto-generated method stub

36.Log.d("ddd","jpeg");

37.}

38.};

39.public MySurfaceView(Context context) {

40.super(context);

41.holder = getHolder();//获得surfaceHolder引用

42.holder.addCallback(this);

43.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置类型

44.}

45.public void tackPicture() {

46.myCamera.takePicture(null,null,null);

47.}

48.public void voerTack() {

49.myCamera.startPreview();

50.}

51.@Override

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

53.myCamera.startPreview();

54.}

55.@Override

56.public void surfaceCreated(SurfaceHolder holder) {

57.// TODO Auto-generated method stub

58.if(myCamera == null) {

59.myCamera = Camera.open();//开启相机,不能放在构造函数中,不然不会显示画面.

60.try {

61.myCamera.setPreviewDisplay(holder);

62.} catch (IOException e) {

63.// TODO Auto-generated catch block

64.e.printStackTrace();

65.}

66.}

67.}

68.

69.@Override

70.public void surfaceDestroyed(SurfaceHolder holder) {

71.// TODO Auto-generated method stub

72.myCamera.stopPreview();//停止预览

73.myCamera.release();//释放相机资源

74.myCamera = null;

75.}

76.}
复制代码
CameraTest_3.java

Java代码:

01.import android.app.Activity;

02.import android.os.Bundle;

03.import android.view.View;

04.import android.view.View.OnClickListener;

05.

06.public class CameraTest_3 extends Activity implements OnClickListener {

07./** Called when the activity is first created. */

08.MySurfaceView mySurface;

09.boolean isClicked = false;

10.@Override

11.public void onCreate(Bundle savedInstanceState) {

12.super.onCreate(savedInstanceState);

13.mySurface = new MySurfaceView(this);

14.setContentView(mySurface);

15.mySurface.setOnClickListener(this);

16.}

17.

18.@Override

19.public void onClick(View v) {

20.// TODO Auto-generated method stub

21.if(!isClicked)

22.{

23.mySurface.tackPicture();

24.isClicked = true;

25.}else {

26.mySurface.voerTack();

27.isClicked = false;

28.}

29.

30.}


这样就是实现了拍照的功能,那么怎样要图片保存呢?那么这是就需要在那个参数中的jpeg的
方法里面进行处理了,那个方法的data参数,就是相片的数据。
我们通过BitmapFactory.decodeByteArray(data, 0, data.length)来获得图片并通过io处理,将图片保存到想要保存的位置
下面这段代码,是将照片保存到/sdcard/wjh.jpg;并把一些没有用到的代码全部删掉,剩下一些必须的代码

MySurfaceView.java

Java代码:

01.package eoe.wjh.camera;

02.

03.import java.io.BufferedInputStream;

04.import java.io.BufferedOutputStream;

05.import java.io.File;

06.import java.io.FileOutputStream;

07.import java.io.OutputStream;

08.import android.content.Context;

09.import android.graphics.Bitmap;

10.import android.graphics.BitmapFactory;

11.import android.graphics.PixelFormat;

12.import android.hardware.Camera;

13.import android.hardware.Camera.PictureCallback;

14.import android.hardware.Camera.ShutterCallback;

15.import android.util.Log;

16.import android.view.SurfaceHolder;

17.import android.view.SurfaceView;

18.

19.public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{

20.SurfaceHolder holder;

21.Camera myCamera;

22.private PictureCallback jpeg = new PictureCallback() {

23.@Override

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

25.// TODO Auto-generated method stub

26.try {

27.Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length);

28.File file = new File("/sdcard/wjh.jpg");

29.BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));

30.bm.compress(Bitmap.CompressFormat.JPEG,100,bos);

31.bos.flush();

32.bos.close();

33.}catch(Exception e) {

34.e.printStackTrace();

35.}

36.};

37.public MySurfaceView(Context context) {

38.super(context);

39.holder = getHolder();//获得surfaceHolder引用

40.holder.addCallback(this);

41.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置类型

42.}

43.public void tackPicture() {

44.myCamera.takePicture(null,null,jpeg);

45.}

46.public void voerTack() {

47.myCamera.startPreview();

48.}

49.

50.@Override

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

52.myCamera.startPreview();

53.}

54.@Override

55.public void surfaceCreated(SurfaceHolder holder) {

56.if(myCamera == null) {

57.myCamera = Camera.open();//开启相机,不能放在构造函数中,不然不会显示画面.

58.try {

59.myCamera.setPreviewDisplay(holder);

60.} catch (IOException e) {

61.// TODO Auto-generated catch block

62.e.printStackTrace();

63.}

64.}

65.}

66.@Override

67.public void surfaceDestroyed(SurfaceHolder holder) {

68.// TODO Auto-generated method stub

69.myCamera.stopPreview();//停止预览

70.myCamera.release();//释放相机资源

71.myCamera = null;

72.}

73.}
复制代码
注意,这是必须添加在sd卡上写数据的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

(7)能够拍照了,这下子要考虑如何让图片更好看了,这显然是专业人士的强项,但是我们在程序上,也可以做一些处理,
向上面的那些,因为我直接把surfaceView当做整体布局,就可能出现屏幕被拉开了,不是很好看,所以这时,就可以不要把surfaceView弄成整体布局,把他弄到到一个布局管理器,在设置相关的参数.这是需要注意的是有些参数不能随便乱设,

如以下代码:

Java代码:

01.Camera.Parameters parames = myCamera.getParameters();//获得参数对象

02.parames.setPictureFormat(PixelFormat.JPEG);//设置图片格式

03.parames.setPreviewSize(640,480);//这里面的参数只能是几个特定的参数,否则会报错.(176*144,320*240,352*288,480*360,640*480)

04.myCamera.setParameters(parames);
复制代码 还有自动对焦,当然有些手机没有这个功能,自动对焦是通过autoFocus()这个方法调用一个自动对焦的接口,并在里面进行处理。
注意,这个方法必须在startPreview()和stopPreview()中间。
AutoFocusCallback是自动对焦的接口,实现它必须实现public void onAutoFocus(boolean success, Camera camera)这个方法,所以我们可以将拍照方法放在这里面,然后对焦后再进行拍摄。效果会好很多。
注意自动对焦需要添加<uses-feature android:name="android.hardware.camera.autofocus" />下面我叫直接把上面的使用例子直接写出。

CameraTest_4.java

Java代码:
01.import java.io.BufferedOutputStream;

02.import java.io.File;

03.import java.io.FileOutputStream;

04.import java.io.IOException;

05.import android.app.Activity;

06.import android.content.pm.ActivityInfo;

07.import android.graphics.Bitmap;

08.import android.graphics.BitmapFactory;

09.import android.graphics.PixelFormat;

10.import android.hardware.Camera;

11.import android.hardware.Camera.AutoFocusCallback;

12.import android.hardware.Camera.PictureCallback;

13.import android.os.Bundle;

14.import android.view.SurfaceHolder;

15.import android.view.SurfaceView;

16.import android.view.View;

17.import android.view.Window;

18.import android.view.SurfaceHolder.Callback;

19.import android.view.View.OnClickListener;

20.

21.

22.public class CameraTest_4 extends Activity implements

23.Callback, OnClickListener, AutoFocusCallback{

24.SurfaceView mySurfaceView;//surfaceView声明

25.SurfaceHolder holder;//surfaceHolder声明

26.Camera myCamera;//相机声明

27.String filePath="/sdcard/wjh.jpg";//照片保存路径

28.boolean isClicked = false;//是否点击标识

29.//创建jpeg图片回调数据对象

30.PictureCallback jpeg = new PictureCallback() {

31.@Override

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

33.// TODO Auto-generated method stub

34.try {// 获得图片

35.Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length);

36.File file = new File(filePath);

37.BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));

38.bm.compress(Bitmap.CompressFormat.JPEG, 100, bos);//将图片压缩到流中

39.bos.flush();//输出

40.bos.close();//关闭

41.}catch(Exception e) {

42.e.printStackTrace();

43.}

44.}

45.};

46./** Called when the activity is first created. */

47.@Override

48.public void onCreate(Bundle savedInstanceState) {

49.super.onCreate(savedInstanceState);

50.requestWindowFeature(Window.FEATURE_NO_TITLE);//无标题

51.//设置拍摄方向

52.this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

53.setContentView(R.layout.main);

54.//获得控件

55.mySurfaceView = (SurfaceView)findViewById(R.id.surfaceView1);

56.//获得句柄

57.holder = mySurfaceView.getHolder();

58.//添加回调

59.holder.addCallback(this);

60.//设置类型

61.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

62.//设置监听

63.mySurfaceView.setOnClickListener(this);

64.}

65.@Override

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

67.// TODO Auto-generated method stub

68.//设置参数并开始预览

69.Camera.Parameters params = myCamera.getParameters();

70.params.setPictureFormat(PixelFormat.JPEG);

71.params.setPreviewSize(640,480);

72.myCamera.setParameters(params);

73.myCamera.startPreview();

74.}

75.@Override

76.public void surfaceCreated(SurfaceHolder holder) {

77.// TODO Auto-generated method stub

78.//开启相机

79.if(myCamera == null) {

80.myCamera = Camera.open();

81.try {

82.myCamera.setPreviewDisplay(holder);

83.} catch (IOException e) {

84.// TODO Auto-generated catch block

85.e.printStackTrace();

86.}

87.}

88.}

89.@Override

90.public void surfaceDestroyed(SurfaceHolder holder) {

91.// TODO Auto-generated method stub

92.//关闭预览并释放资源

93.myCamera.stopPreview();

94.myCamera.release();

95.myCamera = null;

96.}

97.@Override

98.public void onClick(View v) {

99.// TODO Auto-generated method stub

100.if(!isClicked) {

101.myCamera.autoFocus(this);//自动对焦

102.isClicked = true;

103.}else {

104.myCamera.startPreview();//开启预览

105.isClicked = false;

106.}

107.}

108.@Override

109.public void onAutoFocus(boolean success, Camera camera) {

110.// TODO Auto-generated method stub

111.if(success) {

112.//设置参数,并拍照

113.Camera.Parameters params = myCamera.getParameters();

114.params.setPictureFormat(PixelFormat.JPEG);

115.params.setPreviewSize(640,480);

116.myCamera.setParameters(params);

117.myCamera.takePicture(null, null, jpeg);

118.}

119.}

120.

121.}
复制代码
main.xml

Java代码:

01.<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"

02.androidrientation="vertical"

03.android:layout_width="fill_parent"

04.android:layout_height="fill_parent"

05.>

06.<surfaceview android:id="@+id/surfaceView1"

07.android:layout_width="640px"

08.android:layout_height="480px"

09.android:layout_gravity="center">
复制代码
AndroidManifest.xml

Java代码:

01.<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"

02.package="com.wjh.camera"

03.android:versionCode="1"

04.android:versionName="1.0">

05.<uses-sdk android:minSdkVersion="7" />

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

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

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

09.<application android:icon="@drawable/icon" android:label="@string/app_name">

10.<activity android:name=".CameraTest_4" android:label="@string/app_name">

11.<intent-filter>

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

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

14.</intent-filter>

15.</activity>

16.</application>

17.</manifest>

更多相关文章

  1. smack 源码分析- PacketWriter (android上实现长连接)
  2. Android多媒体框架初步分析
  3. Android设置透明、半透明等效果
  4. android Camera照相机技术(一)
  5. Android四大基本组件介绍与生命周期
  6. android 带箭头的textview文字伸缩效果
  7. 浅析Android中Handler机制
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Android(安卓)启动浏览器的方法
  2. android发送QQ邮件(带附件)
  3. Android如何使用Notification进行通知
  4. android获取手机信息大全
  5. Android(安卓)之 下拉框(Spinner)的使用
  6. Suggestion: add 'tools:replace="androi
  7. android JNI处理图片的例子
  8. Android(安卓)读取Resources和Assets
  9. android获取手机序列号
  10. Android日语输入法Simeji使用示例