Android – 相机设置
http://www.eoeandroid.com/thread-69555-1-1.html
Android 浅谈相机研发(一)
http://www.eoeandroid.com/thread-101808-1-1.html

Android游戏《歪把子炮》源码
http://www.eoeandroid.com/thread-197425-1-1.html

Android 中PopupWindow 实例源码
http://www.eoeandroid.com/thread-197426-1-1.html

分享45个android实例源码,很好很强大.大家赶快来收藏吧!!
http://www.eoeandroid.com/thread-185986-1-1.html

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


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

Intent intent = new Intent(); //调用照相机    intent.setAction("android.media.action.STILL_IMAGE_CAMERA");     startActivity(intent);     想要测试的,可以直接新建一个项目,并且把主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

import java.io.IOException;      public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{           SurfaceHolder holder;         Camera myCamera;  

public MySurfaceView(Context context) { super(context); holder = getHolder();//获得surfaceHolder引用 holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置类型 } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { myCamera.startPreview(); } @Override public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub if(myCamera == null) { myCamera = Camera.open();//开启相机,不能放在构造函数中,不然不会显示画面. try { myCamera.setPreviewDisplay(holder); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub myCamera.stopPreview();//停止预览 myCamera.release();//释放相机资源 myCamera = null; Log.d("ddd", "4"); } }

而且必须给应用添加权限: <uses-permission android:name="android.permission.CAMERA"></uses-permission>

(5)能够预览了,接下来就是拍照了,拍照用到了一个camera.tackPiture()这个方法,这个方法,有三个参数分别是
ShutterCallBack shutter,PictureCallBack raw,PictureCallBack jpeg.
下面是对他们的实现

private ShutterCallback shutter = new ShutterCallback() {                  @Override         public void onShutter() {               // TODO Auto-generated method stub            Log.d("ddd", "shutter");                 }     };       private PictureCallback raw = new PictureCallback() {                  @Override           public void onPictureTaken(byte[] data, Camera camera) {               // TODO Auto-generated method stub             Log.d("ddd", "raw");                    }    };         private PictureCallback jpeg = new PictureCallback() {          @Override        public void onPictureTaken(byte[] data, Camera camera) {               // TODO Auto-generated method stub            Log.d("ddd","jpeg");           }      };     

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

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

package com.wjh.camera;         import java.io.IOException;    import android.content.Context;       ....     public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{           SurfaceHolder holder;        Camera myCamera;           private ShutterCallback shutter = new ShutterCallback() {           @Override              public void onShutter() {                 // TODO Auto-generated method stub                   Log.d("ddd", "shutter");             }        };           private PictureCallback raw = new PictureCallback() {            @Override               public void onPictureTaken(byte[] data, Camera camera) {                 // TODO Auto-generated method stub                 Log.d("ddd", "raw");                             }        };           private PictureCallback jpeg = new PictureCallback() {                          @Override             public void onPictureTaken(byte[] data, Camera camera) {                   // TODO Auto-generated method stub                 Log.d("ddd","jpeg");                            }           };           public MySurfaceView(Context context)        {             super(context);             holder = getHolder();//获得surfaceHolder引用             holder.addCallback(this);             holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置类型          }           public void tackPicture()        {             myCamera.takePicture(null,null,null);         }           public void voerTack()        {             myCamera.startPreview();         }        @Override           public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {               myCamera.startPreview();                }           @Override           public void surfaceCreated(SurfaceHolder holder) {               // TODO Auto-generated method stub             if(myCamera == null)           {                   myCamera = Camera.open();//开启相机,不能放在构造函数中,不然不会显示画面.                 try {                       myCamera.setPreviewDisplay(holder);                 } catch (IOException e) {                       // TODO Auto-generated catch block                       e.printStackTrace();                  }             }                }           @Override           public void surfaceDestroyed(SurfaceHolder holder) {                 // TODO Auto-generated method stub             myCamera.stopPreview();//停止预览             myCamera.release();//释放相机资源            myCamera = null;           }       }

CameraTest_3.java

import android.app.Activity;    ....  import android.view.View.OnClickListener;       public class CameraTest_3 extends Activity implements OnClickListener  {           /** Called when the activity is first created. */           MySurfaceView mySurface;        boolean isClicked = false;           @Override           public void onCreate(Bundle savedInstanceState) {               super.onCreate(savedInstanceState);               mySurface = new MySurfaceView(this);            setContentView(mySurface);            mySurface.setOnClickListener(this);           }           @Override          public void onClick(View v) {               // TODO Auto-generated method stub               if(!isClicked)               {              mySurface.tackPicture();               isClicked = true;               }else               {                   mySurface.voerTack();                isClicked = false;              }              }    

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

package com.wjh.camera;       import java.io.BufferedInputStream;     import java.io.BufferedOutputStream;       .....     public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback{           SurfaceHolder holder;         Camera myCamera;           private PictureCallback jpeg = new PictureCallback() {          @Override               public void onPictureTaken(byte[] data, Camera camera) {                   // TODO Auto-generated method stub                  try                   {                       Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length);                     File file = new File("/sdcard/wjh.jpg");                     BufferedOutputStream bos  = new BufferedOutputStream(new FileOutputStream(file));                     bm.compress(Bitmap.CompressFormat.JPEG,100,bos);                     bos.flush();                     bos.close();                }catch(Exception e)                   {                       e.printStackTrace();                 }             }           };         public MySurfaceView(Context context)          {             super(context);             holder = getHolder();//获得surfaceHolder引用            holder.addCallback(this);             holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置类型            }         public void tackPicture()           {             myCamera.takePicture(null,null,jpeg);           }        public void voerTack()        {             myCamera.startPreview();       }          @Override         public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {             myCamera.startPreview();               }           @Override         public void surfaceCreated(SurfaceHolder holder) {               // TODO Auto-generated method stub             if(myCamera == null)               {                myCamera = Camera.open();//开启相机,不能放在构造函数中,不然不会显示画面.                   try {                       myCamera.setPreviewDisplay(holder);                } catch (IOException e) {                       // TODO Auto-generated catch block                     e.printStackTrace();                 }               }                }         @Override           public void surfaceDestroyed(SurfaceHolder holder) {               // TODO Auto-generated method stub               myCamera.stopPreview();//停止预览             myCamera.release();//释放相机资源             myCamera = null;           }    }     

CameraTest_3.java跟上面的一样
注意,这是必须添加在sd卡上写数据的权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

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

这是需要注意的是有些参数不能随便乱设,
如以下代码:Camera.Parameters parames = myCamera.getParameters();//获得参数对象
parames.setPictureFormat(PixelFormat.JPEG);//设置图片格式
parames.setPreviewSize(640,480);//这里面的参数只能是几个特定的参数,否则会报错.(176*144,320*240,352*288,480*360,640*480)
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

import java.io.BufferedOutputStream;     import java.io.File;     import java.io.FileOutputStream;    import java.io.IOException;     import android.app.Activity;     import android.content.pm.ActivityInfo;     import android.graphics.Bitmap;     import android.graphics.BitmapFactory;     import android.graphics.PixelFormat;     import android.hardware.Camera;     import android.hardware.Camera.AutoFocusCallback;    import android.hardware.Camera.PictureCallback;    import android.os.Bundle;    import android.view.SurfaceHolder;     import android.view.SurfaceView;     import android.view.View;     import android.view.Window;     import android.view.SurfaceHolder.Callback;     import android.view.View.OnClickListener;       public class CameraTest_4 extends Activity implements Callback, OnClickListener, AutoFocusCallback{             SurfaceView mySurfaceView;//surfaceView声明         SurfaceHolder holder;//surfaceHolder声明         Camera myCamera;//相机声明        String filePath="/sdcard/wjh.jpg";//照片保存路径         boolean isClicked = false;//是否点击标识           //创建jpeg图片回调数据对象           PictureCallback jpeg = new PictureCallback() {                         @Override            public void onPictureTaken(byte[] data, Camera camera) {                   // TODO Auto-generated method stub                 try                   {// 获得图片                   Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length);                 File file = new File(filePath);                 BufferedOutputStream bos =  new BufferedOutputStream(new FileOutputStream(file));                   bm.compress(Bitmap.CompressFormat.JPEG, 100, bos);//将图片压缩到流中                 bos.flush();//输出                 bos.close();//关闭                 }catch(Exception e)                   {                       e.printStackTrace();                }           }         };          /** Called when the activity is first created. */           @Override       public void onCreate(Bundle savedInstanceState) {               super.onCreate(savedInstanceState);               requestWindowFeature(Window.FEATURE_NO_TITLE);//无标题                       //设置拍摄方向               this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);               setContentView(R.layout.main);               //获得控件             mySurfaceView = (SurfaceView)findViewById(R.id.surfaceView1);               //获得句柄               holder = mySurfaceView.getHolder();               //添加回调               holder.addCallback(this);               //设置类型             holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);               //设置监听             mySurfaceView.setOnClickListener(this);        }        @Override          public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {               // TODO Auto-generated method stub             //设置参数并开始预览               Camera.Parameters params = myCamera.getParameters();               params.setPictureFormat(PixelFormat.JPEG);             params.setPreviewSize(640,480);             myCamera.setParameters(params);             myCamera.startPreview();                     }          @Override           public void surfaceCreated(SurfaceHolder holder) {            // TODO Auto-generated method stub            //开启相机               if(myCamera == null)               {                 myCamera = Camera.open();                   try {                       myCamera.setPreviewDisplay(holder);                } catch (IOException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                 }               }                 }           @Override           public void surfaceDestroyed(SurfaceHolder holder) {               // TODO Auto-generated method stub             //关闭预览并释放资源               myCamera.stopPreview();            myCamera.release();             myCamera = null;                 }           @Override        public void onClick(View v) {               // TODO Auto-generated method stub            if(!isClicked)            {                 myCamera.autoFocus(this);//自动对焦                 isClicked = true;             }else              {                 myCamera.startPreview();//开启预览                 isClicked = false;            }                  }         @Override           public void onAutoFocus(boolean success, Camera camera) {            // TODO Auto-generated method stub              if(success)             {                   //设置参数,并拍照                 Camera.Parameters params = myCamera.getParameters();                 params.setPictureFormat(PixelFormat.JPEG);                 params.setPreviewSize(640,480);                 myCamera.setParameters(params);                 myCamera.takePicture(null, null, jpeg);               }             }       }  

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"             package="com.wjh.camera"         android:versionCode="1"        android:versionName="1.0">      <uses-sdk android:minSdkVersion="7" />        <uses-permission android:name="android.permission.CAMERA"></uses-permission>   <uses-feature android:name="android.hardware.camera.autofocus" />   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>         <application android:icon="@drawable/icon" android:label="@string/app_name">           <activity android:name=".CameraTest_4"                     android:label="@string/app_name">              <intent-filter>                   <action android:name="android.intent.action.MAIN" />                   <category android:name="android.intent.category.LAUNCHER" />               </intent-filter>             </activity>       </application>   </manifest>   

main.xml

<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"         androidrientation="vertical"         android:layout_width="fill_parent"         android:layout_height="fill_parent"           >           <surfaceview android:id="@+id/surfaceView1"       android:layout_width="640px"          android:layout_height="480px"          android:layout_gravity="center">     

更多相关文章

  1. Android底部导航栏实现(四)之TabLayout+ViewPager
  2. 在android里保存数据的三种形式(Saving Data)
  3. LayoutInflater.inflate()方法的介绍
  4. 使用ListView应该注意的地方
  5. onRetainNonConfigurationInstance和getLastNonConfigurationIns
  6. Android学习笔记三
  7. Android(安卓)SDK下载和更新失败的解决方法
  8. android与php的json交互
  9. Android(安卓)实现部分文字高亮的三种方法

随机推荐

  1. 安卓如何限制横屏和竖屏
  2. Android添加一个系统service
  3. Activity配置属性
  4. android自定义属性 format类型
  5. Android学习笔记之mainfest文件中android
  6. 装载 联系人2.0的相关处理
  7. Android中设置文本颜色的三种方法
  8. android junit入门(一) JUNIT测试
  9. android监听网络变化
  10. Android淘宝好评星级进度条RatingBar原来