android拍照

jopen 12年前發布 | 16K 次閱讀 html5未來 log4j2

android拍照

前言

    android編碼中有2種方式可以調用到系統的攝像頭,一種是通過Intent調用系統的照相機Activity;另外一種就是通過編碼調用Camera api.

1.  Intent調用系統照相Activity

通過Intent直接調用系統提供的照相機功能,復用它的拍照Activity,這是最簡單和最方便的辦法,不需要考慮手機的兼容性問題,比如預覽拍照圖片大小等,代碼如下:

Intent i = new Intent("android.media.action.IMAGE_CAPTURE");

startActivityForResult(i, C.REQUEST_CODE_CAMERA);

 

然后在onActivityResult中獲取返回的數據即可

if(resultCode==RESULT_OK){

    Bundle extras = data.getExtras();

    if(extras!=null){

       Bitmap bitmap = (Bitmap) extras.get(C.CODE_PHOTO_BITMAP_DATA);

       … …

    }

}

但是這樣獲取的圖片是縮小過的, 如果要獲取原始的相片就要在調用的時候就要指定相片生成的路徑,下面的代碼即可.

i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(tempPath)));

指定相片的類型,代碼示例.

i.putExtra("outputFormat", Bitmap.CompressFormat.PNG.name());

控制拍照的橫豎屏.

i.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION, Configuration.ORIENTATION_LANDSCAPE);

2.  Android編碼拍照

直接調用攝像頭的API,自己編寫類似取景框的Activity,這樣靈活度更大,但是你需要考慮比較底層的東西.要知道android有多個版本,攝像頭的分辨率也不一樣,需要先獲取當前相機的分辨率組合,然后再編寫各種屏幕分辨率組合的布局等等.

而且Android提供的SDK(android.hardware.Camera)不能正常的使用豎屏(portrait layout)加載照相機,當用豎屏模式加載照相機時會產生以下情況:1. 照相機成像左傾90;2. 照相機成像長寬比例不對(失比).原因是:攝像頭對照物的映射是Android底層固定的,landscape方式為正,并且產生大小為320*480的像,如果換成portrait方式了,攝像頭還是產生320*480的像,但要對應的放入到一個480*320的屏內,此時會失比,并且產生了左傾90度的情況.如圖所示

這種情況可以通過復雜的編碼可以校正.

   設置Camera的參數來實現轉變圖片預覽角度,但是這種方式并不是對所有的Camera都有效果的.

    Camera.Parameters parameters = camera.getParameters();

    parameters.set("orientation", "portrait");

    parameters.set("rotation", 90);

    camera.setParameters(parameters);

 

   在獲取拍攝相片之后進行旋轉校正, 但這里同時也要如果圖片太大了,會造成內存溢出.

    Matrix m = new Matrix();

    m.postRotate(90);

    m.postScale(balance, balance);

    Bitmap.createBitmap(tempBitmap, 0, 0, tempBitmap.getWidth(), tempBitmap.getHeight(),m, true);

 

Camera示例代碼:

public class CameraDemoActivityextends Activity implements SurfaceHolder.Callback{

    private Camera              mCamera;

    private Button              mButton;

    private SurfaceView         mSurfaceView;

    private SurfaceHolder       holder;

    private AutoFocusCallback   mAutoFocusCallback   = new AutoFocusCallback();

 

    @Override

    public void onCreate(Bundle savedInstanceState){

       super.onCreate(savedInstanceState);

       setContentView(R.layout.main);

       /* SurfaceHolder設置 */

       mSurfaceView = (SurfaceView)findViewById(R.id.mSurfaceView);

       holder = mSurfaceView.getHolder();

       holder.addCallback(CameraDemoActivity.this);

       holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

       /* 設置拍照ButtonOnClick事件處理 */

       mButton = (Button)findViewById(R.id.myButton);

       mButton.setOnClickListener(new Button.OnClickListener(){

           @Override

           public void onClick(View arg0){

              /* 告動對焦后拍照 */

              mCamera.autoFocus(mAutoFocusCallback);

           }

       });

    }

 

    @Override

    public void surfaceCreated(SurfaceHolder surfaceholder){

       try{

           /* 打開相機, */

           mCamera = Camera.open();

           mCamera.setPreviewDisplay(holder);

       }catch(IOException exception){

           mCamera.release();

           mCamera = null;

       }

    }

 

    @Override

    public void surfaceChanged(SurfaceHolder surfaceholder, int format, int w, int h){

       /* 相機初始化 */

       initCamera();

    }

 

    @Override

    public void surfaceDestroyed(SurfaceHolder surfaceholder){

       stopCamera();

       mCamera.release();

       mCamera = null;

    }

 

    /* 拍照的method */

    private void takePicture(){

       if(mCamera != null){

           mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);

       }

    }

 

    private ShutterCallback  shutterCallback   = new ShutterCallback(){

       public void onShutter(){

       /* 按下快門瞬間會調用這里的程序 */

       }

    };

 

    private PictureCallback  rawCallback       = new PictureCallback(){

                                          public void onPictureTaken(byte[] _data, Camera _camera){

       /* 要處理raw data?? */

       }

    };

 

    private PictureCallback  jpegCallback  = new PictureCallback(){

       public void onPictureTaken(byte[] _data, Camera _camera){

           /* 取得相片 */

           try{

               /* 讓相片顯示3秒后圳重設相機 */

               Thread.sleep(3000);

               /* 重新設定Camera */

               stopCamera();

               initCamera();

            }catch(Exception e){

               e.printStackTrace();

            }

        }

};

 

    /* 告定義class AutoFocusCallback */

    public final class AutoFocusCallback implements android.hardware.Camera.AutoFocusCallback{

       public void onAutoFocus(boolean focused, Camera camera){

           /* 對到焦點拍照 */

           if(focused){

              takePicture();

           }

       }

    };

 

    /* 相機初始化的method */

    private void initCamera(){

       if(mCamera != null){

           try{

              Camera.Parameters parameters = mCamera.getParameters();

              /*

               * 設定相片大小為1024*768,格式為JPG

               */

              parameters.setPictureFormat(PixelFormat.JPEG);

              parameters.setPictureSize(1024, 768);

              mCamera.setParameters(parameters);

              /* 打開預覽畫面 */

              mCamera.startPreview();

           }catch(Exception e){

              e.printStackTrace();

           }

       }

    }

 

    /* 停止相機的method */

    private void stopCamera(){

       if(mCamera != null){

           try{

              /* 停止預覽 */

              mCamera.stopPreview();

           }catch(Exception e){

              e.printStackTrace();

           }

       }

    }

}

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!