在APP中使用camera的兩種方式
-
調(diào)用系統(tǒng)相機(jī),或具有相機(jī)功能的應(yīng)用婉烟。
/** * 啟動相機(jī)應(yīng)用 * 函數(shù)名為按鈕的點(diǎn)擊事件名startCamera */ public void startCamera(View view){ //ACTION_IMAGE_CAPTURE捕捉圖形功能 Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivity(intent); }
-
獲取相機(jī)拍照的圖片需要調(diào)用startActivityForResult方法鼻弧,在重寫onActivityResult方法设江。
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode==RESULT_OK){ if (requestCode==REQUSET_CODE){ /** * 通過Bundle取出的圖片只是一張縮略圖,為了放在數(shù)據(jù)溢出 */ Bundle bundle=data.getExtras(); Bitmap bitmap= (Bitmap) bundle.get("data"); imageView.setImageBitmap(bitmap); } } }
-
要想獲取圖片的原始質(zhì)量温数,需要把在onCreate方法中自定義一個存儲路徑
/** * 獲取系統(tǒng)存儲路徑 */ mFilePath= Environment.getExternalStorageDirectory().getPath(); mFilePath=mFilePath+"/"+"temp.png";
-
在按鈕的點(diǎn)擊事件的方法中創(chuàng)建一個URI對象绣硝,再把它指向我們創(chuàng)建的文件路徑對象蜻势,最后把系統(tǒng)默認(rèn)的圖片存儲路徑更改到我們自己創(chuàng)建的路徑撑刺。
//ACTION_IMAGE_CAPTURE捕捉圖形功能 Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //URI指向我們創(chuàng)建的文件對象 Uri photeUri=Uri.fromFile(new File(mFilePath)); intent.putExtra(MediaStore.EXTRA_OUTPUT,photeUri); startActivityForResult(intent, REQUSET_2);
-
在onActivityResult方法中創(chuàng)建一個FileInputStream對象,把存儲路徑封裝到該對象中握玛,再把輸入流封裝到Bitmap中够傍。
FileInputStream fileInputStream=null; try { fileInputStream=new FileInputStream(mFilePath); Bitmap bitmap= BitmapFactory.decodeStream(fileInputStream); imageView.setImageBitmap(bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); }finally { try { fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } }
-
這樣就可以獲取到圖片的原始質(zhì)量了甫菠,但在我的手機(jī)上運(yùn)行的時候,ImageView并沒有顯示出該圖片冕屯。android studio打印的信息是:Bitmap too large to be uploaded into a texture寂诱。這并不是一個異常或者錯誤安聘,好像意思是圖片過大痰洒。查閱資料后發(fā)現(xiàn)android默認(rèn)啟動硬件加速,而硬件加速中OpenGL對于內(nèi)存是有限制的浴韭。解決的辦法之一就是在AndroidManifest中的activity里取消硬件加速丘喻。
<activity android:name=".MainActivity" android:hardwareAccelerated="false">
- 自定義相機(jī)。
-
在AndroidManifest中注冊應(yīng)用具有相近功能念颈。
<intent-filter> <action android:name="android.media.action.IMAGE_CAPTURE"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter>
-
并且申請拍照權(quán)限:
<uses-permission android:name="android.permission.CAMERA"/>
-
呈現(xiàn)相機(jī)的實(shí)時預(yù)覽用到SurfaceView組件泉粉。在自己新建的相機(jī)活動里實(shí)現(xiàn)SurfaceHolder.Callback接口,并在onCreate方法中初始化SurfaceHolder榴芳。
mHolder=mPreView.getHolder(); mHolder.addCallback(this);
-
寫下三個方法:
/** * 獲取Camera對象 * @return */ private Camera getCamera(){ Camera camera; try{ camera=Camera.open(); }catch (Exception e){ camera=null; e.getStackTrace(); } return camera; } /** * 開始預(yù)覽相機(jī) */ private void setStartPreview(Camera camera,SurfaceHolder holder) { //將Camera與surfaceView進(jìn)行綁定 try { camera.setPreviewDisplay(holder); //將camera豎屏顯示 camera.setDisplayOrientation(90); camera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } /** * 釋放相機(jī)資源 */ private void releaseCamera(){ if (mCamera!=null){ //將相機(jī)回調(diào)置空 mCamera.setPreviewCallback(null); //取消相機(jī)的取景功能 mCamera.stopPreview(); mCamera.release(); mCamera=null; } }
-
將上述三個方法與activity的生命周期綁定起來:
@Override protected void onResume() { super.onResume(); if (mCamera==null){ getCamera(); if (mHolder!=null){ setStartPreview(mCamera,mHolder); } }
}
@Override protected void onPause() { super.onPause(); releaseCamera(); }
-
實(shí)現(xiàn)SurfaceHolder.Callback的三個方法:
@Override public void surfaceCreated(SurfaceHolder holder) { setStartPreview(mCamera,mHolder); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { mCamera.stopPreview(); setStartPreview(mCamera,mHolder); } @Override public void surfaceDestroyed(SurfaceHolder holder) { releaseCamera(); }
-
實(shí)現(xiàn)拍照功能的點(diǎn)擊事件
public void capture(View view){ //獲取相機(jī)參數(shù) Camera.Parameters parameters=mCamera.getParameters(); //設(shè)置拍照格式 parameters.setPictureFormat(ImageFormat.JPEG); //設(shè)置拍照大小 parameters.setPictureSize(800,400); //設(shè)置自動對焦 parameters.setFlashMode(Camera.Parameters.FOCUS_MODE_AUTO); mCamera.autoFocus(new Camera.AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { mCamera.takePicture(null,null,mPictureCallback); } }); }
-
我們需要把相機(jī)拍照所得的圖片顯示在另一個activity里面的ImageView里嗡靡,在自動對焦方法onAutoFocus里面的mCamera.takePicture方法傳入一個PictureCallback對象,該對象實(shí)現(xiàn)一個匿名內(nèi)部類窟感,在內(nèi)部類里面onPictureTaken(byte[] data, Camera camera) 方法里獲取我們所拍的圖片讨彼。
@Override public void onPictureTaken(byte[] data, Camera camera) { //將數(shù)據(jù)寫入SD卡的temp.png文件當(dāng)中 File tempFile=new File("/sdcard/temp.png"); try { FileOutputStream fileOutputStream=new FileOutputStream(tempFile); fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } };
-
在該方法內(nèi)部就得啟動另一個activity了:ResultAty。
Intent intent=new Intent(CustomCamera.this,ResultAty.class); intent.putExtra("picPath",tempFile.getAbsolutePath()); startActivity(intent); CustomCamera.this.finish();
-
新建ResultAty類肌括,獲取Intent傳給ResultAty的圖片存儲路徑点骑。
String path=getIntent().getStringExtra("picPath");
-
對圖像的顯示角度進(jìn)行調(diào)整。
ImageView imageView= (ImageView) findViewById(R.id.pic); try { FileInputStream fis=new FileInputStream(path); //把圖像轉(zhuǎn)換成字節(jié)流 Bitmap bitmap=BitmapFactory.decodeStream(fis); Matrix matrix=new Matrix(); matrix.setRotate(90); //調(diào)整角度 bitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true); imageView.setImageBitmap(bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); }