2010年11月20日 星期六

[Android] 如何開啟Camera拍照 (Camera Capture)



這陣子在研究Camera錄影 , 但是網路上很多文章說模擬器似乎不能成功錄影 , 錄音倒是可以 , 所以退而求其次使用Camera來拍照 , 模擬器真的是一個模擬器....不能完全模擬出實機的情況 , 如果把code轉到實機上去跑 , 應該有很多要Debug的東西....下面是Layout佈局 , 沒啥特別的



   
   






如果要開啟Camera鏡頭的話 , 需要在AndroidManifest.xml中註冊屬性

    
        
            
                
                
            
        
    
  
 
  
 


接下來是程式碼的部分
package com.android;

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.Parameters;
import android.hardware.Camera.PictureCallback;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.widget.Button;

public class Camera_Capture extends Activity implements Button.OnClickListener , SurfaceHolder.Callback , Camera.ShutterCallback
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);       
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        //這行程式碼也可以隱藏Title Bar但是位置要放對
        setContentView(R.layout.main);
        
        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        //強制讓螢幕的內容呈現橫向
        
        SurfaceView SV = (SurfaceView) findViewById(R.id.SurfaceView);
        surfaceHolder = SV.getHolder();
        surfaceHolder.addCallback(this);
        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        
        captureButton = (Button) findViewById(R.id.captureButton);
        captureButton.setOnClickListener(this);
        
        TempFile = this.getFilesDir();
    }
    
    Button captureButton;    
    SurfaceHolder surfaceHolder;    
    
 Camera mCamera;
 Parameters mParameters;
 
 File TempFile;
 
 Camera.PictureCallback TakeJpeg = new Camera.PictureCallback()
 {
  @Override
  public void onPictureTaken(byte[] data, Camera camera)
  {
   // TODO Auto-generated method stub
   
            try {              
                 Bitmap mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);  
           File temp = File.createTempFile("PhotoTemp", ".jpg", TempFile);
           //在模擬器中開一個暫存檔 路徑為 //data/data/YourPackageName/files/
           //在DDMS視窗中可以看到
           
           BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(temp));  
                 mBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos);  
                 //採用壓縮轉檔方法
                 //format 只有JPEG , PNG 兩種
                 //quality Hint to the compressor, 0-100. 0 meaning compress for small size, 100 meaning compress for max quality. Some formats, like PNG which is lossless, will ignore the quality setting
                 //stream The outputstream to write the compressed data.
                                
                 bos.flush();
                 bos.close();
   } catch (IOException e)
   {    
    e.printStackTrace();
   }   
   mCamera.startPreview();
   //由於拍照完後 , PreView會停止
   //故重新啟動PreView
   
  }  
 };
 
 Camera.PictureCallback TakeRAW = new Camera.PictureCallback()
 {
  @Override
  public void onPictureTaken(byte[] data, Camera camera)
  {
   //raw: the callback for raw (uncompressed) image data, or null
   Log.d("onTakeRAW",""+data);
  }  
 };
 
 Camera.PictureCallback PostView = new Camera.PictureCallback()
 {
  @Override
  public void onPictureTaken(byte[] data, Camera camera)
  {
   //postview: callback with postview image data, may be null
   Log.d("onPostView",""+data);
  }  
 };
 
 @Override
 public void onShutter()
 {
  //Called as near as possible to the moment when a photo is captured from the sensor. 
  //This is a good opportunity to play a shutter sound or give other feedback of camera operation. 
  //This may be some time after the photo was triggered, but some time before the actual data is available.
     Log.d("onShutter()","onShutter()");
 }

 @Override
 public void onClick(View v)
 {  
  switch(v.getId())
  {
    case R.id.captureButton:
    mCamera.takePicture(this, TakeRAW, PostView ,TakeJpeg);  
    break;
  }
 }
 
 @Override
 public void surfaceCreated(SurfaceHolder holder)
 {  
  mCamera = Camera.open();
  
  try {            
            mParameters = mCamera.getParameters();
            mParameters.setPictureFormat(PixelFormat.JPEG);
            //mParameters.setPreviewSize(320, 480);
            //設定螢幕Preview大小 , 對模擬器拍出的圖片沒影響
            //mParameters.setPictureSize(320, 480);
            //設定圖片解析度大小
            mCamera.setParameters(mParameters);
            mCamera.setPreviewDisplay(holder);

        } catch (IOException exception)
        {
            mCamera.release();
            mCamera = null;            
        }
        mCamera.startPreview();
        
 }

 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width,
   int height)
 {
  // TODO Auto-generated method stub
 } 

 @Override
 public void surfaceDestroyed(SurfaceHolder holder)
 {  
  mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
 }
}


關於takePicture的函式說明 , 有三個PictureCallback的物件當作參數 , 然後針對這三個物件實作程式內容 , 不知道是否在同一個PictureCallback就能統一處理


以下是畫面截圖





然後不管你怎麼拍照 , 結果永遠是下面那張圖....







沒有留言:

張貼留言

Google Analytics