Android如何调用拍照程序实现连拍

原创 2012年03月24日 14:13:16
可以实现调用摄像头拍照,后台自动保存照片。

例子非常详细,经过测试后的。


关于评论中很多童鞋说不能连拍,在这里澄清一下:连拍功能在这里确实没有体现,我只是贴出了部分代码,实现了不阻塞主线程,且拍照完成后继续停留在拍摄界面,如果大家想要实现连拍,可以在onClick()方法中循环调用takePicture()方法,想要连拍几张自己定义,代码是用来学习的,希望大家可以体谅。

public class SnapPicActivity extends Activity 
  implements SurfaceHolder.Callback{
	final private static String STILL_IMAGE_FILE = "capture.jpg";
	final private static int IMAGE_NUM= 3;
	private String strCaptureFilePath = "/sdcard/camera_snap.jpg"; 
	private String TAG = "IsiCamera2Activity";
	private Button btn_capture; 
	private Button btn_sum; 
	private Camera camera = null; 
	private SurfaceHolder mSurfaceHolder; 
	private SurfaceView mSurfaceView01; 
	private FrameLayout mFrameLayout01;
	private boolean bPreviewing =false; 
	private int intScreenWidth; 
	private int intScreenHeight; 
	@Override 
	public void onCreate(Bundle savedInstanceState) { 
		super.onCreate(savedInstanceState); 
		/* 使应用程序全屏幕运行,不使用title bar */ 
		requestWindowFeature(Window.FEATURE_NO_TITLE); 
		setContentView(R.layout.main); 
		
		/* 取得屏幕解析像素 */ 
		getDisplayMetrics(); 
		findViews();
		getSurfaceHolder(); 
		btn_capture.setOnClickListener(new Button.OnClickListener() { 
			@Override 
			public void onClick(View v) { 
				jumpOutAToast("test onclick");
                //这里实现模拟连拍逻辑
                for(int i=0; i<IMAGE_NUM; i++){
                	takeAPicture();
                 }
                
            }
        });
    }
	
    @Override
    protected void onPause() {     
	    //被交换到后台时执行    
	    //camera.release();
	    //camera = null;
	    bPreviewing = false;
	    jumpOutAToast("test onPause");
	    super.onPause();
    }
    
    @Override 
    public void onStop() {
	    jumpOutAToast("test onStop");
	    resetCamera();
	    super.onStop();
    }
    @Override
    protected void onResume() {
	    try {
	    	initCamera();
	    } catch(IOException e ) {
	    	Log.e(TAG,"initCamera() in Resume() erorr!");
	    }
	    jumpOutAToast("test onResume");
	    super.onResume();
    }
  
	/* function:
	 * 非preview时:实例化Camera,开始preview
	 * 非preview时and相机打开时:再设置一次preview
	 * preview时:不动作
	 */
    private void initCamera() throws IOException
    {
      if(!bPreviewing)
      {
        /* 若相机非在预览模式,则打开相机 */
        camera = Camera.open();
        camera.setDisplayOrientation(90);
      }
      //非预览时and相机打开时,开启preview
      if (camera != null && !bPreviewing)
      {
        Log.i(TAG, "inside the camera");
        /* 创建Camera.Parameters对象 */
        Camera.Parameters parameters = camera.getParameters();
        /* 设置相片格式为JPEG */
        parameters.setPictureFormat(PixelFormat.JPEG);
        /* 指定preview的屏幕大小 */
        parameters.setPreviewSize(intScreenWidth, intScreenHeight);
        /* 设置图片分辨率大小 */
        parameters.setPictureSize(intScreenWidth, intScreenHeight);
        /* 将Camera.Parameters设置予Camera */
        camera.setParameters(parameters);
        /* setPreviewDisplay唯一的参数为SurfaceHolder */
        camera.setPreviewDisplay(mSurfaceHolder);
        /* 立即运行Preview */
        camera.startPreview();
        bPreviewing = true;
      }
    }
/* func:停止preview,释放Camera对象*/
    private void resetCamera()
    {
      if (camera != null && bPreviewing)
      {
        camera.stopPreview();
        /* 释放Camera对象 */
        camera.release();
        camera = null;
        bPreviewing = false;
      }
    }
/* func:停止preview*/
    private void stopPreview() {
    if (camera != null && bPreviewing) {
            Log.v(TAG, "stopPreview");
            camera.stopPreview();
        }
    }
    private void takeAPicture() {
        if (camera != null && bPreviewing) 
        {
          /* 调用takePicture()方法拍照 */
          camera.takePicture
          (shutterCallback, rawCallback, jpegCallback);//调用PictureCallback interface的对象作为参数
        }
    }
/*func:获取屏幕分辨率*/
    private void getDisplayMetrics() {
    	DisplayMetrics dm = new DisplayMetrics();
    	getWindowManager().getDefaultDisplay().getMetrics(dm);
    	intScreenWidth = dm.widthPixels;
    	intScreenHeight = dm.heightPixels;
    	Log.i(TAG, Integer.toString(intScreenWidth));
    }
    
    private ShutterCallback shutterCallback = new ShutterCallback()
    { 
      public void onShutter() 
      { 
        // Shutter has closed 
      } 
    }; 
     
    private PictureCallback rawCallback = new PictureCallback() 
    { 
      public void onPictureTaken(byte[] _data, Camera _camera) 
      { 
        // TODO Handle RAW image data 
      } 
    }; 


    private PictureCallback jpegCallback = new PictureCallback() 
    {
      public void onPictureTaken(byte[] _data, Camera _camera)
      {
    	  //保存
     Bitmap  bitmap=BitmapFactory.decodeByteArray(data, 0, data.length);
     if(bitmap!=null){
    	 File myCaptureFile=new File(f"/sdcard/test.jpg");
             
         BufferedOutputStream bos=null;
          try {
	         bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
	         bitmap.compress(CompressFormat.JPEG, mPicQuality, bos);
	         bos.close();
	         bitmap.recycle();
          } catch (FileNotFoundException e) {
        	  e.printStackTrace();
          } catch (IOException e) {
        	  e.printStackTrace();
          }  
     }
     resetCamera();
     try {
    	 initCamera();
     } catch(Exception e) {
    	 Log.e(TAG, "initCamera Error after snapping");
     }
      }
    };
/* get a fully initialized SurfaceHolder*/
    private void getSurfaceHolder() {   
		mSurfaceHolder = mSurfaceView01.getHolder();
		mSurfaceHolder.addCallback(this);
		mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }
/* 把SurfaceView 加到FrameLayout 里*/
    private void addSurfaceViewToFrameLayout() {
    	mFrameLayout01.addView(mSurfaceView01);
    }
/*func:弹出toast,主要做测试用 */
    private void jumpOutAToast(String string) {
    	Toast.makeText(IsiCamera2Activity.this, string,Toast.LENGTH_SHORT).show();
    }
/* func:宣告界面元件Button capture,FrameLayout frame*/
    private void findViews() {
    	btn_capture = (Button) findViewById(R.id.btn_capture);
        btn_sum = (Button) findViewById(R.id.btn_sum);
        /* 以SurfaceView作为相机Preview之用 */
        mSurfaceView01 = (SurfaceView) findViewById(R.id.mSurfaceView01);
    } 
    @Override    
    public void surfaceCreated(SurfaceHolder holder) {
	    if(!bPreviewing) {
		    camera = Camera.open();
		    camera.setDisplayOrientation(90);
	    }
    }
    @Override
	public void surfaceChanged(SurfaceHolder holder,int format,int width,int height) {
    	if(bPreviewing) {
    		camera.stopPreview();
    	}
    	Camera.Parameters params = camera.getParameters();
    	params.setPreviewSize(width, height);
    	camera.setParameters(params);
    	try {
    		camera.setPreviewDisplay(mSurfaceHolder);
    	} catch(IOException e) {
    		e.printStackTrace();
    	}
    	camera.startPreview();
    	bPreviewing = true;
	}
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		camera.stopPreview();
		bPreviewing = false;
		camera.release();
		mSurfaceHolder = null;
	}
}



main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:weightSum="1">
<TextView  
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="@string/hello"
    />


<LinearLayout 
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button 
android:id="@+id/btn_capture"
android:layout_height="wrap_content"
android:text="@string/str_btn_capture"
android:layout_gravity="left" android:layout_width="148dp"/>
<Button 
android:id="@+id/btn_sum"
android:layout_height="wrap_content"
android:text="@string/str_btn_closeAndSum" 
android:layout_gravity="right" android:layout_width="154dp"/>
</LinearLayout>


<SurfaceView 
android:id="@+id/mSurfaceView01"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1"/>


</LinearLayout>

manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.demo.android.IsiCamera2"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="10" />
  <!-- 操作sd卡的权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 打开操作拍照的权限  包括摄像头、操作SD卡、自动聚焦 -->
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
<uses-feature android:name="android.hardware.camera" />

    <application android:label="@string/app_name" android:icon="@drawable/isilogo">
        <activity android:name=".IsiCamera2Activity"
                  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>


Android自定义相机实现N连拍

昨天有朋友让我帮他实现一个进入系统相机实现3连拍,然后自动返回拍到的结果,一可以我觉得这个需求有点可笑,但是作为技术人员,我还是值得探索一下,所以我就自己写了个相机,改系统的有点费劲。给我一个Came...
  • Jiang_Rong_Tao
  • Jiang_Rong_Tao
  • 2017年03月16日 12:21
  • 3599

Android拍照,连拍以及自动拍照

  • 2016年12月05日 10:07
  • 21.07MB
  • 下载

android camera程序源代码,可连拍,未添加储存功能,注释详细

http://download.csdn.net/download/vctisildur/3565707
  • u011277123
  • u011277123
  • 2016年08月04日 18:40
  • 530

Android相机连续拍照实现连拍功能

在此处说明一点,本例子实现的是三连拍,通过异步任务类实现的存储,最重要的一点:Camera的回调是异步方式的,三连拍不能够使用简单的for循环,我在这里使用的递归方法。 1.CameraPrevie...
  • a_fly_pig
  • a_fly_pig
  • 2016年10月24日 16:49
  • 941

Android自动化基础—简单例子(启动相机拍照-重复执行1000次)

转载:http://blog.csdn.net/gb112211/article/details/42354671 一个简单的测试需求如下:     测试相机的过程中发现一极低概率性问题,在进入相...
  • lzpdz
  • lzpdz
  • 2017年03月16日 14:55
  • 1026

【Android】自定义相机的实现(支持连续拍照、前后摄像头切换、连续对焦)

~转载请注明http://blog.csdn.net/u013015161/article/details/46921257介绍这几天,写了一个自定义照相机的demo,支持连续拍照和摄像头切换。由于自...
  • u013015161
  • u013015161
  • 2015年07月17日 02:33
  • 6822

android camera程序源代码,可连拍,未添加储存功能,注释详细

  • 2011年09月01日 10:07
  • 53KB
  • 下载

一份很易懂的Android手机拍照代码

轻松的拍照 这个教程可以教你如何用一个已经安装的相机APP来拍照 首先来请求一个相机权限 如果拍照这个功能在你的应用里是很核心的功能,那么你可以在商店里要求用户的设备必须要有摄像头才能下载安装...
  • imwangji
  • imwangji
  • 2015年01月11日 00:25
  • 802

如何将camera连拍速度降为3fps

[DESCRIPTION]  将camera的连拍速度降为3fps [SOLUTION] 在ModeActor.java中的ActorContinuousShot类中: 将onPictureT...
  • andylao62
  • andylao62
  • 2015年05月14日 01:49
  • 566

Android多媒体应用开发系列(二) 项目重构以及连拍和定时自动拍照的实现

本文基于上一篇Android拍照的介绍,对代码进行了简单重构,在此基础上完成了连拍和定时拍照功能。...
  • yjp19871013
  • yjp19871013
  • 2016年12月05日 09:35
  • 1397
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android如何调用拍照程序实现连拍
举报原因:
原因补充:

(最多只允许输入30个字)