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?implementsSurfaceHolder.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);
???????/*?設置拍照Button的OnClick事件處理?*/
???????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?implementsandroid.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();
?????????? }
?????? }
??? }
}
總結
- 上一篇: Android自定义进度条
- 下一篇: android 如何做记住密码