[Android]使用相機物件

張貼者: Mark | 清晨7:40

Android使用相機可以有兩個方法,一種是呼叫相機應用程式,另一種就是實作相機應用程式套用在自己的應用程式上,以上這兩種都是一樣麻煩,不過後一種變化性比較大,可以加入一些設定的功能,今天就來提第二種方法,使用前先聊聊一些android提供的library。
SurfaceView
SurfaceView介面元件可以想成是一塊畫布,程式開發者可以在上面畫上任何東西。在這個程式中SurfaceView是用來顯示從相機取得的畫面。SurfaceView的存取要透過SurfaceHolder物件,而SurfaceHolde類別的addCallback方法能讓我們設定當SurfaceView建立、改變與銷毀時該做的事,因此我們可於SurfaceView建立時打開相機、啟動預覽功能,而於銷毀時關掉相機。下列圖示可以幫助了解,故在layout就要加入SurfaceView這個元件使用。
clip_image001


1.加入permission ~ 在應用程式使用相機功能
<uses-permission android:name="android.permission.CAMERA"></uses-permission>





2.應用程式實作相機物件 ~ 於應用程式類別實作相機物件,實作SurfaceHolder物件,實作成功時,Eclipse工具會告知是否也引用surfaceChanged /surfaceCreated /surfaceDestroyed 函式,在此建議引用喔。




public class TestCamera extends Activity implements SurfaceHolder.Callback 
{
@Override
public void surfaceChanged (SurfaceHolder surfaceholder, int format, int w, int h)
{ set parameters, start preview; }
@Override
public void surfaceCreated (SurfaceHolder surfaceholder)
{ initialize camera; }
@Override
public void surfaceDestroyed (SurfaceHolder surfaceholder)
{ release camera; }
}





3.實作應用程式 ~ 此程式為相機應用程式,其功能為拍照/影像存檔/live show影像於手機螢幕上。實作後就可以在手機上看到相機live show畫面於手機螢幕上,開發者就可以加入一些功能。




package com.amaker.ch11.app;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MainActivity extends Activity {
// 宣告拍照介面元件SurfaceView
private SurfaceView surfaceView;
// 宣告介面控制元件SurfaceHolder
private SurfaceHolder surfaceHolder;
// 宣告照相機
private Camera camera;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 實例化拍照介面元件
surfaceView = (SurfaceView)findViewById(R.id.preview);
// 從SurfaceView中取得SurfaceHolder
surfaceHolder = surfaceView.getHolder();
// 為SurfaceHolder 新增回呼函數
surfaceHolder.addCallback(surfaceCallback);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

// 回應按鍵事件
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode==KeyEvent.KEYCODE_CAMERA||keyCode==KeyEvent.KEYCODE_SEARCH){
takePic();
return true;
}
return super.onKeyDown(keyCode, event);
}
// 拍照方法
private void takePic(){
// 停止預覽
camera.stopPreview();
// 拍照
camera.takePicture(null,null, pictureCallback);
}
// 照片回呼
Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {
//@Override
public void onPictureTaken(byte[] data, Camera camera) {
new SavePictureTask().execute(data);
camera.startPreview();
}
};

// 保存照片任務類別
class SavePictureTask extends AsyncTask<byte[],String,String>{
@Override
protected String doInBackground(byte[]... params) {
// 建立檔案
File picture = new File(Environment.getExternalStorageDirectory(),"picture.jpg");
// 如果檔案存在則刪除
if(picture.exists())picture.delete();
try {
// 取得檔案輸出串流
FileOutputStream fos = new FileOutputStream(picture.getPath());
// 寫入內容
fos.write(params[0]);
// 關閉文件串流
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
// SurfaceHodler 回呼。處理打開相機、關閉相機以及照片尺寸的改變
SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
//@Override
public void surfaceCreated(SurfaceHolder holder) {
// 打開相機
camera = Camera.open();
try {
// 設定預覽
camera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
}

//@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// 取得相機參數
Camera.Parameters parameters = camera.getParameters();
// 設定照片大小
parameters.setPreviewSize(width, height);
// 設定照片格式
parameters.setPictureFormat(PixelFormat.JPEG);
// 設定相機參數
camera.setParameters(parameters);
// 開始預覽
camera.startPreview();
}

//@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// 停止預覽
camera.stopPreview();
// 釋放相機資源
camera.release();
camera = null;
}
};
}





4.應用程式下載~下載完成後,請給讚!您的鼓勵是支持我的動力



下載連結:[按此下載]  備份下載:[下載一][下載二

分享好文: 讚 ! 分享到塗鴉牆
0 意見