android照相機

    使用相機的兩種方式:
    1 使用Intent跳轉到系統相機,action為:android.media.action.STILL_IMAGE_CAMERA 這中方法一般是最常用的 方便簡單 畢竟自定義相機比較復雜 而且花費時間比較長

    代碼片段,雙擊復制

    01

    02

    03

    04

    05

    06

    07

    08

    09

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    package

    barry.android.c;

    import

    java.io.File;

    import

    java.io.FileNotFoundException;

    import

    java.io.FileOutputStream;

    import

    java.io.IOException;

    import

    android.app.Activity;

    import

    android.content.Intent;

    import

    android.graphics.Bitmap;

    import

    android.os.Bundle;

    import

    android.os.Environment;

    import

    android.provider.MediaStore;

    import

    android.util.Log;

    import

    android.view.View;

    import

    android.view.View.OnClickListener;

    import

    android.widget.Button;

    import

    android.widget.ImageView;

    /**

    *
    * @title MyCaremaActivity.java


    *
    @package barry.android.c


    *
    @email cjhszh@126.com


    *
    @author szh


    *
    @update 2013-1-11 上午9:27:03


    *
    @description

    */

    public

    class

    MyCaremaActivity
    extends

    Activity {


    @Override


    public

    void

    onCreate(Bundle savedInstanceState) {


    super.onCreate(savedInstanceState);


    setContentView(R.layout.main);


    Button
    button = (Button) findViewById(R.id.button);


    button.setOnClickListener(new

    OnClickListener() {


    @Override


    public

    void

    onClick(View v) {


    Intent
    intent =
    new

    Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    //open
    camera


    startActivityForResult(intent,
    1);


    }


    });


    }


    @Override


    protected

    void

    onActivityResult(
    int

    requestCode,
    int

    resultCode, Intent data) {


    super.onActivityResult(requestCode,
    resultCode, data);


    if

    (resultCode == Activity.RESULT_OK) {


    String
    sdStatus = Environment.getExternalStorageState();


    if

    (sdStatus.equals(Environment.MEDIA_MOUNTED)) {
    //
    檢測sd是否可用


    Log.v("TestFile",


    sdStatus+"SD
    card is not avaiable/writeable right now."
    );


    }


    Bundle
    bundle = data.getExtras();


    Bitmap
    bitmap = (Bitmap) bundle.get(
    "data");//
    獲取相機返回的數據,並轉換為Bitmap圖片格式


    FileOutputStream
    b =
    null;


    File
    file =
    new

    File(
    "/sdcard/myImage/");


    file.mkdirs();//
    創建文件夾


    String
    fileName =
    "/sdcard/myImage/111.jpg";


    try

    {


    b
    =
    new

    FileOutputStream(fileName);


    bitmap.compress(Bitmap.CompressFormat.JPEG,
    100,
    b);
    //
    把數據寫入文件


    }
    catch

    (FileNotFoundException e) {


    e.printStackTrace();


    }
    finally

    {


    try

    {


    b.flush();


    b.close();


    }
    catch

    (IOException e) {


    e.printStackTrace();


    }


    }


    ((ImageView)
    findViewById(R.id.imageView)).setImageBitmap(bitmap);
    //
    將圖片顯示在ImageView裡


    }


    }

    }

    2 (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,並在裡面實現瞭照相機的預覽功能.這個我覺得最簡單的照相機預覽代碼:

    代碼片段,雙擊復制

    01

    02

    03

    04

    05

    06

    07

    08

    09

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    102

    103

    104

    105

    106

    107

    108

    109

    110

    111

    112

    113

    114

    115

    116

    117

    118

    119

    120

    121

    122

    123

    124

    125

    126

    127

    128

    129

    130

    131

    132

    133

    134

    135

    136

    137

    138

    139

    140

    141

    142

    143

    144

    145

    package

    com.hipikids.mycamerademo;

    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;

    /**

    *
    * @title MainActivity.java

    *

    *
    @package com.hipikids.mycamerademo

    *
    @email cjhszh@126.com

    *
    @author szh

    *
    @update 2013-1-10 下午5:21:00

    *
    @description

    */

    public

    class

    MainActivity
    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.activity_main);


    //
    獲得控件


    mySurfaceView
    = (SurfaceView) findViewById(R.id.surface);


    //
    獲得句柄


    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();
    //
    open display


    }


    @Override


    public

    void

    surfaceCreated(SurfaceHolder holder) {


    //
    TODO Auto-generated method stub


    //
    開啟相機


    if

    (myCamera ==
    null)
    {


    myCamera
    = Camera.open();
    //
    this method is a static method


    try

    {


    myCamera.setPreviewDisplay(holder);
    //
    connection SurfaceHolder


    }
    catch

    (IOException e) {


    //
    TODO Auto-generated catch block


    e.printStackTrace();


    }


    }


    }


    @Override


    public

    void

    surfaceDestroyed(SurfaceHolder holder) {


    //
    TODO Auto-generated method stub


    //
    關閉預覽並釋放資源


    myCamera.stopPreview();
    //
    close display


    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);


    }


    }

    }

    最後別忘瞭加權限

    代碼片段,雙擊復制

    01

    02

    03

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


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


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

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *