這陣子在研究Camera錄影 , 但是網路上很多文章說模擬器似乎不能成功錄影 , 錄音倒是可以 , 所以退而求其次使用Camera來拍照 , 模擬器真的是一個模擬器....不能完全模擬出實機的情況 , 如果把code轉到實機上去跑 , 應該有很多要Debug的東西....下面是Layout佈局 , 沒啥特別的
如果要開啟Camera鏡頭的話 , 需要在AndroidManifest.xml中註冊屬性
接下來是程式碼的部分
package com.android; 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.Parameters; import android.hardware.Camera.PictureCallback; import android.media.MediaRecorder; import android.os.Bundle; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.Window; import android.widget.Button; public class Camera_Capture extends Activity implements Button.OnClickListener , SurfaceHolder.Callback , Camera.ShutterCallback { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); //這行程式碼也可以隱藏Title Bar但是位置要放對 setContentView(R.layout.main); this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //強制讓螢幕的內容呈現橫向 SurfaceView SV = (SurfaceView) findViewById(R.id.SurfaceView); surfaceHolder = SV.getHolder(); surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); captureButton = (Button) findViewById(R.id.captureButton); captureButton.setOnClickListener(this); TempFile = this.getFilesDir(); } Button captureButton; SurfaceHolder surfaceHolder; Camera mCamera; Parameters mParameters; File TempFile; Camera.PictureCallback TakeJpeg = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { // TODO Auto-generated method stub try { Bitmap mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length); File temp = File.createTempFile("PhotoTemp", ".jpg", TempFile); //在模擬器中開一個暫存檔 路徑為 //data/data/YourPackageName/files/ //在DDMS視窗中可以看到 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(temp)); mBitmap.compress(Bitmap.CompressFormat.JPEG, 80, bos); //採用壓縮轉檔方法 //format 只有JPEG , PNG 兩種 //quality Hint to the compressor, 0-100. 0 meaning compress for small size, 100 meaning compress for max quality. Some formats, like PNG which is lossless, will ignore the quality setting //stream The outputstream to write the compressed data. bos.flush(); bos.close(); } catch (IOException e) { e.printStackTrace(); } mCamera.startPreview(); //由於拍照完後 , PreView會停止 //故重新啟動PreView } }; Camera.PictureCallback TakeRAW = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { //raw: the callback for raw (uncompressed) image data, or null Log.d("onTakeRAW",""+data); } }; Camera.PictureCallback PostView = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { //postview: callback with postview image data, may be null Log.d("onPostView",""+data); } }; @Override public void onShutter() { //Called as near as possible to the moment when a photo is captured from the sensor. //This is a good opportunity to play a shutter sound or give other feedback of camera operation. //This may be some time after the photo was triggered, but some time before the actual data is available. Log.d("onShutter()","onShutter()"); } @Override public void onClick(View v) { switch(v.getId()) { case R.id.captureButton: mCamera.takePicture(this, TakeRAW, PostView ,TakeJpeg); break; } } @Override public void surfaceCreated(SurfaceHolder holder) { mCamera = Camera.open(); try { mParameters = mCamera.getParameters(); mParameters.setPictureFormat(PixelFormat.JPEG); //mParameters.setPreviewSize(320, 480); //設定螢幕Preview大小 , 對模擬器拍出的圖片沒影響 //mParameters.setPictureSize(320, 480); //設定圖片解析度大小 mCamera.setParameters(mParameters); mCamera.setPreviewDisplay(holder); } catch (IOException exception) { mCamera.release(); mCamera = null; } mCamera.startPreview(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceDestroyed(SurfaceHolder holder) { mCamera.stopPreview(); mCamera.release(); mCamera = null; } }
關於takePicture的函式說明 , 有三個PictureCallback的物件當作參數 , 然後針對這三個物件實作程式內容 , 不知道是否在同一個PictureCallback就能統一處理
以下是畫面截圖
然後不管你怎麼拍照 , 結果永遠是下面那張圖....
沒有留言:
張貼留言