生活随笔
收集整理的這篇文章主要介紹了
android之相机开发
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
?http://blog.csdn.net/jason0539/article/details/10125017 android之相機開發(fā)?
分類:?android 基礎知識2013-08-20 22:32?9774人閱讀? Android
在android中應用相機功能,一般有兩種:一種是直接調用系統(tǒng)相機,一種自己寫的相機。
我將分別演示兩種方式的使用:
第一種:是使用Intent跳轉到系統(tǒng)相機,action為:android.media.action.STILL_IMAGE_CAMERA
關鍵代碼:
[java]?view plaincopyprint?
Intent?intent?=?new?Intent();?intent.setAction("android.media.action.STILL_IMAGE_CAMERA");??????startActivity(intent);?????? 例子:
[java]?view plaincopyprint?
import?android.app.Activity;??????import?android.content.Intent;??????import?android.os.Bundle;??????public?class?CameraTest_2?extends?Activity?{??????????????@Override??????????public?void?onCreate(Bundle?savedInstanceState)?{??????????????super.onCreate(savedInstanceState);??????????????setContentView(R.layout.main);??????????????Intent?intent?=?new?Intent();??????????intent.setAction("android.media.action.STILL_IMAGE_CAMERA");???????????????startActivity(intent);??????????}??????}?????? 想要測試的,可以直接新建一個項目,并且把主activity的代碼換成上面的,然后運行,我測試了一下,上面這個代碼并不
需要權限,畢竟只是調用系統(tǒng)自帶的程序。
當然網(wǎng)上還有一些其他相關的調用方法,只要設置對了action,那么系統(tǒng)就會調用系統(tǒng)自帶的相機.
第二種:
(1)首先我們要自己創(chuàng)建一個照相界面,必須考慮用什么控件顯示照相機中的預覽效果,顯然android已經幫我們做好了選擇,那就是SurfaceView
控制SurfaceView需要一個surfaceHolder,他是系統(tǒng)提供的一個用來設置SurfaceView的一個對象,可以通過surfaceView.getHolder()這個方法來獲得.
Camera提供一個setPreviewDisplay(SurfaceHolder)的方法來連接surfaceHolder,并通過他來控制surfaceView.
而我們則使用android的Camera類提供了startPreview()和stopPreview()來開啟和關閉預覽.
關系如下:
Camera -- -->SurfaceHolder------>SurfaceView.
(2)知道怎么預覽了,當然也要知道怎么開啟相機.Camera.open()這是個靜態(tài)方法,如果相機沒有別人用著,則會返回一個 相機引用,如果被人用著,則會拋出異常。很奇怪的是,這個方法,不能隨便放,如放在構造方法或者onCreate()方法中,都會照成沒有預覽效果.
(3)
SurfaceHolder.Callback,這是個holder用來顯示surfaceView 數(shù)據(jù)的接口,他分別必須實現(xiàn)3個方法
surfaceCreated()這個方法是surface 被創(chuàng)建后調用的
surfaceChanged()這個方法是當surfaceView發(fā)生改變后調用的
surfaceDestroyed()這個是當surfaceView銷毀時調用的.
surfaceHolde通過addCallBack()方法將響應的接口綁定到他身上.
surfaceHolder還必須設定一個setType()方法,查看api的時候,發(fā)現(xiàn)這個方法已經過時,但是不寫,又會報錯
(4)
我用以上知識寫了一個MySurfaceView類,他繼承于SurfaceView,并在里面實現(xiàn)了照相機的預覽功能.這個我覺得最簡單的照相機預覽代碼:
MySurfaceView.java:
[java]?view plaincopyprint?
import?java.io.IOException;??????import?android.content.Context;??????import?android.graphics.PixelFormat;??????import?android.hardware.Camera;??????import?android.util.Log;??????import?android.view.SurfaceHolder;??????import?android.view.SurfaceView;??????public?class?MySurfaceView?extends?SurfaceView?implements?SurfaceHolder.Callback{??????????SurfaceHolder?holder;??????????Camera?myCamera;??????????public?MySurfaceView(Context?context)??????????{??????????????super(context);??????????????holder?=?getHolder();?????????holder.addCallback(this);??????????????holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);????}??????@Override??????????public?void?surfaceCreated(SurfaceHolder?holder)?{??????????????????????if(myCamera?==?null)??????????????{??????????????????myCamera?=?Camera.open();????????????try?{??????????????????????myCamera.setPreviewDisplay(holder);??????????????????}?catch?(IOException?e)?{??????????????????????????????????????e.printStackTrace();??????????????????}??????????????}?????????????????}??????????@Override??????????public?void?surfaceChanged(SurfaceHolder?holder,?int?format,?int?width,??????????????????int?height)?{??????????????myCamera.startPreview();??????????????????}??????????????@Override??????????public?void?surfaceDestroyed(SurfaceHolder?holder)?{??????????????????????myCamera.stopPreview();?????????myCamera.release();?????????myCamera?=?null;??????????????Log.d("ddd",?"4");????????????}??????}?????? 主activity代碼:
[java]?view plaincopyprint?
import?android.app.Activity;??????import?android.os.Bundle;??????import?android.view.View;??????import?android.view.View.OnClickListener;??????public?class?CameraTest_3?extends?Activity??{??????????????MySurfaceView?mySurface;??????????@Override??????????public?void?onCreate(Bundle?savedInstanceState)?{??????????????super.onCreate(savedInstanceState);??????????????mySurface?=?new?MySurfaceView(this);??????????????setContentView(mySurface);??????????}??????}?????? 而且必須給應用添加權限:
[html]?view plaincopyprint?
<uses-permission?android:name="android.permission.CAMERA"></uses-permission>?? (5)能夠預覽了,接下來就是拍照了,拍照用到了一個camera.tackPiture()這個方法,這個方法,有三個參數(shù)分別是
ShutterCallBack shutter,PictureCallBack raw,PictureCallBack jpeg.
下面是對他們的實現(xiàn)
[java]?view plaincopyprint?
private?ShutterCallback?shutter?=?new?ShutterCallback()?{????????????????????@Override??????????public?void?onShutter()?{??????????????????????Log.d("ddd",?"shutter");??????????????}??????};??????private?PictureCallback?raw?=?new?PictureCallback()?{????????????????????@Override??????????public?void?onPictureTaken(byte[]?data,?Camera?camera)?{??????????????????????Log.d("ddd",?"raw");????????????}??????};??????private?PictureCallback?jpeg?=?new?PictureCallback()?{????????????????????@Override??????????public?void?onPictureTaken(byte[]?data,?Camera?camera)?{??????????????????????Log.d("ddd","jpeg");????????????}??????};?????? 當開始拍照時,會依次調用shutter的onShutter()方法,raw的onPictureTaken方法,jpeg的onPictureTaken方法.
三個參數(shù)的作用是shutter--拍照瞬間調用,raw--獲得沒有壓縮過的圖片數(shù)據(jù),jpeg---返回jpeg的圖片數(shù)據(jù)
當你不需要對照片進行處理,可以直接用null代替.
注意,當調用camera.takePiture方法后,camera關閉了預覽,這時需要調用startPreview()來重新開啟預覽。
我用以上知識,加到上面的那個例子,就形成了下面的代碼:
MySurfaceView.java:
[java]?view plaincopyprint?
package?jason.camera;??????import?java.io.IOException;??????import?android.content.Context;??????import?android.graphics.PixelFormat;??????import?android.hardware.Camera;??????import?android.hardware.Camera.PictureCallback;??????import?android.hardware.Camera.ShutterCallback;??????import?android.util.Log;??????import?android.view.SurfaceHolder;??????import?android.view.SurfaceView;??????public?class?MySurfaceView?extends?SurfaceView?implements?SurfaceHolder.Callback{??????????SurfaceHolder?holder;??????????Camera?myCamera;??????????private?ShutterCallback?shutter?=?new?ShutterCallback()?{????????????????????????????@Override??????????????public?void?onShutter()?{??????????????????????????????Log.d("ddd",?"shutter");????????????????????????????????}??????????};??????????private?PictureCallback?raw?=?new?PictureCallback()?{????????????????????????????@Override??????????????public?void?onPictureTaken(byte[]?data,?Camera?camera)?{??????????????????????????????Log.d("ddd",?"raw");????????????????????????????????}??????????};??????????private?PictureCallback?jpeg?=?new?PictureCallback()?{????????????????????????????@Override??????????????public?void?onPictureTaken(byte[]?data,?Camera?camera)?{??????????????????????????????Log.d("ddd","jpeg");????????????????????????????????}??????????};??????????public?MySurfaceView(Context?context)??????????{??????????????super(context);??????????????holder?=?getHolder();?????????holder.addCallback(this);??????????????holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);????}??????????public?void?tackPicture()??????????{??????????????myCamera.takePicture(null,null,null);??????????}??????????public?void?voerTack()??????????{??????????????myCamera.startPreview();??????????}??????????@Override??????????public?void?surfaceChanged(SurfaceHolder?holder,?int?format,?int?width,??????????????????int?height)?{??????????????myCamera.startPreview();??????????????????}??????????@Override??????????public?void?surfaceCreated(SurfaceHolder?holder)?{??????????????????????if(myCamera?==?null)??????????????{??????????????????myCamera?=?Camera.open();????????????try?{??????????????????????myCamera.setPreviewDisplay(holder);??????????????????}?catch?(IOException?e)?{??????????????????????????????????????e.printStackTrace();??????????????????}??????????????}?????????????????}??????????@Override??????????public?void?surfaceDestroyed(SurfaceHolder?holder)?{??????????????????????myCamera.stopPreview();?????????myCamera.release();?????????myCamera?=?null;????????????????????????????}??????}?????? 主activity:
[java]?view plaincopyprint?
import?android.app.Activity;??????import?android.os.Bundle;??????import?android.view.View;??????import?android.view.View.OnClickListener;??????public?class?CameraTest_3?extends?Activity?implements?OnClickListener??{??????????????MySurfaceView?mySurface;??????????boolean?isClicked?=?false;??????????@Override??????????public?void?onCreate(Bundle?savedInstanceState)?{??????????????super.onCreate(savedInstanceState);??????????????mySurface?=?new?MySurfaceView(this);??????????????setContentView(mySurface);??????????????mySurface.setOnClickListener(this);??????????}??????????@Override??????????public?void?onClick(View?v)?{??????????????????????if(!isClicked)??????????????{??????????????????mySurface.tackPicture();??????????????????isClicked?=?true;??????????????}else??????????????{??????????????????mySurface.voerTack();??????????????????isClicked?=?false;????????????????????????????????}????????????????????????}?????? 這樣就是實現(xiàn)了拍照的功能,那么怎樣要圖片保存呢?那么這是就需要在那個參數(shù)中的jpeg的
方法里面進行處理了,那個方法的data參數(shù),就是相片的數(shù)據(jù)。
我們通過BitmapFactory.decodeByteArray(data, 0, data.length)來獲得圖片并通過io處理,將圖片保存到想要保存的位置
下面這段代碼,是將照片保存到/sdcard/wjh.jpg;并把一些沒有用到的代碼全部刪掉,剩下一些必須的代碼
[java]?view plaincopyprint?
package?java.camera;??????import?java.io.BufferedInputStream;??????import?java.io.BufferedOutputStream;??????import?java.io.File;??????import?java.io.FileOutputStream;??????import?java.io.IOException;??????import?java.io.OutputStream;??????import?android.content.Context;??????import?android.graphics.Bitmap;??????import?android.graphics.BitmapFactory;??????import?android.graphics.PixelFormat;??????import?android.hardware.Camera;??????import?android.hardware.Camera.PictureCallback;??????import?android.hardware.Camera.ShutterCallback;??????import?android.util.Log;??????import?android.view.SurfaceHolder;??????import?android.view.SurfaceView;??????public?class?MySurfaceView?extends?SurfaceView?implements?SurfaceHolder.Callback{??????????SurfaceHolder?holder;??????????Camera?myCamera;??????????private?PictureCallback?jpeg?=?new?PictureCallback()?{????????????????????????????@Override??????????????public?void?onPictureTaken(byte[]?data,?Camera?camera)?{??????????????????????????????try??????????????????{??????????????????????Bitmap?bm?=?BitmapFactory.decodeByteArray(data,?0,?data.length);??????????????????????File?file?=?new?File("/sdcard/wjh.jpg");??????????????????????BufferedOutputStream?bos???????????????????????=?new?BufferedOutputStream(new?FileOutputStream(file));??????????????????????bm.compress(Bitmap.CompressFormat.JPEG,100,bos);??????????????????????bos.flush();??????????????????????bos.close();??????????????????}catch(Exception?e)??????????????????{??????????????????????e.printStackTrace();??????????????????}??????????????}??????????};??????????public?MySurfaceView(Context?context)??????????{??????????????super(context);??????????????holder?=?getHolder();?????????holder.addCallback(this);??????????????holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);????}??????????public?void?tackPicture()??????????{??????????????myCamera.takePicture(null,null,jpeg);??????????}??????????public?void?voerTack()??????????{??????????????myCamera.startPreview();??????????}??????????@Override??????????public?void?surfaceChanged(SurfaceHolder?holder,?int?format,?int?width,??????????????????int?height)?{??????????????myCamera.startPreview();??????????????????}??????????@Override??????????public?void?surfaceCreated(SurfaceHolder?holder)?{??????????????????????if(myCamera?==?null)??????????????{??????????????????myCamera?=?Camera.open();????????????try?{??????????????????????myCamera.setPreviewDisplay(holder);??????????????????}?catch?(IOException?e)?{??????????????????????????????????????e.printStackTrace();??????????????????}??????????????}?????????????????}??????????@Override??????????public?void?surfaceDestroyed(SurfaceHolder?holder)?{??????????????????????myCamera.stopPreview();????????myCamera.release();????????myCamera?=?null;??????????}??????}?????? 注意,這是必須添加在sd卡上寫數(shù)據(jù)的權限
[html]?view plaincopyprint?
<uses-permission?android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>?? (7)能夠拍照了,這下子要考慮如何讓圖片更好看了,這顯然是專業(yè)人士的強項,但是我們在程序上,也可以做一些處理,
向上面的那些,因為我直接把surfaceView當做整體布局,就可能出現(xiàn)屏幕被拉開了,不是很好看,所以這時,就可以不要把
surfaceView弄成整體布局,把他弄到一個布局管理器,再設置相關的參數(shù).
這時需要注意的是有些參數(shù)不能隨便亂設
如以下代碼:
[java]?view plaincopyprint?
Camera.Parameters?parames?=?myCamera.getParameters();parames.setPictureFormat(PixelFormat.JPEG);parames.setPreviewSize(640,480);myCamera.setParameters(parames);?? 還有自動對焦,當然有些手機沒有這個功能,自動對焦是通過autoFocus()這個方法調用一個自動對焦的接口,并在里面進行處理。
注意,這個方法必須在startPreview()和stopPreview()中間。
AutoFocusCallback是自動對焦的接口,實現(xiàn)它必須實現(xiàn)public void onAutoFocus(boolean success, Camera camera)這個方法,
所以我們可以將拍照方法放在這里面,然后對焦后再進行拍攝。。效果會好很多。
注意自動對焦需要添加
[html]?view plaincopyprint?
<uses-feature?android:name="android.hardware.camera.autofocus"?/>?? ?
下面是主要代碼,直接貼出來了
[java]?view plaincopyprint?
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;??????public?class?CameraTest_4?extends?Activity?implements??????Callback,?OnClickListener,?AutoFocusCallback{??????????SurfaceView?mySurfaceView;????SurfaceHolder?holder;????Camera?myCamera;????String?filePath="/sdcard/wjh.jpg";????boolean?isClicked?=?false;????????PictureCallback?jpeg?=?new?PictureCallback()?{????????????????????????????@Override??????????????public?void?onPictureTaken(byte[]?data,?Camera?camera)?{??????????????????????????????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();??????????????????}????????????????????????????????}??????????};??????????????@Override??????????public?void?onCreate(Bundle?savedInstanceState)?{??????????????super.onCreate(savedInstanceState);??????????????requestWindowFeature(Window.FEATURE_NO_TITLE);????????????????this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);??????????????setContentView(R.layout.main);??????????????????????mySurfaceView?=?(SurfaceView)findViewById(R.id.surfaceView1);??????????????????????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)?{??????????????????????????????Camera.Parameters?params?=?myCamera.getParameters();??????????????params.setPictureFormat(PixelFormat.JPEG);??????????????params.setPreviewSize(640,480);??????????????myCamera.setParameters(params);??????????????myCamera.startPreview();????????????????????????}??????????@Override??????????public?void?surfaceCreated(SurfaceHolder?holder)?{??????????????????????????????if(myCamera?==?null)??????????????{??????????????????myCamera?=?Camera.open();??????????????????try?{??????????????????????myCamera.setPreviewDisplay(holder);??????????????????}?catch?(IOException?e)?{??????????????????????????????????????e.printStackTrace();??????????????????}??????????????}????????????????????????}??????????@Override??????????public?void?surfaceDestroyed(SurfaceHolder?holder)?{??????????????????????????????myCamera.stopPreview();??????????????myCamera.release();??????????????myCamera?=?null;????????????????????????}??????????@Override??????????public?void?onClick(View?v)?{??????????????????????if(!isClicked)??????????????{??????????????????myCamera.autoFocus(this);????????????isClicked?=?true;??????????????}else??????????????{??????????????????myCamera.startPreview();????????????isClicked?=?false;??????????????}????????????????????????}??????????@Override??????????public?void?onAutoFocus(boolean?success,?Camera?camera)?{??????????????????????if(success)??????????????{??????????????????????????????Camera.Parameters?params?=?myCamera.getParameters();??????????????????params.setPictureFormat(PixelFormat.JPEG);??????????????????params.setPreviewSize(640,480);??????????????????myCamera.setParameters(params);??????????????????myCamera.takePicture(null,?null,?jpeg);??????????????}????????????????????????}??????}?????? main.xml:
[html]?view plaincopyprint?
<linearlayout?xmlns:android="http://schemas.android.com/apk/res/android"?????????androidrientation="vertical"??????????android:layout_width="fill_parent"??????????android:layout_height="fill_parent"??????????>??????????<surfaceview?android:id="@+id/surfaceView1"??????????android:layout_width="640px"???????????android:layout_height="480px"???????????android:layout_gravity="center">?????? AndroidManifest.xml:
[html]?view plaincopyprint?
<?xml?version="1.0"?encoding="utf-8"?>????<manifest?xmlns:android="http://schemas.android.com/apk/res/android"??????????package="com.wjh.camera"??????????android:versionCode="1"??????????android:versionName="1.0">????????<uses-sdk?android:minSdkVersion="7"?/>????????<uses-permission?android:name="android.permission.CAMERA"></uses-permission>????????<uses-feature?android:name="android.hardware.camera.autofocus"?/>????????????<uses-permission?android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>????????<application?android:icon="@drawable/icon"?android:label="@string/app_name">????????????<activity?android:name=".CameraTest_4"??????????????????????android:label="@string/app_name">????????????????<intent-filter>????????????????????<action?android:name="android.intent.action.MAIN"?/>????????????????????<category?android:name="android.intent.category.LAUNCHER"?/>????????????????</intent-filter>????????????</activity>????????</application>????</manifest>???? ?
PS:其實自己去實現(xiàn)相機的必要性不大,大部分應用都是直接調用系統(tǒng)的相機,畢竟相機是涉及到一些比較專業(yè)的成像知識.
轉載于:https://www.cnblogs.com/qingchen1984/p/4766395.html
總結
以上是生活随笔為你收集整理的android之相机开发的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。