也較方便的用法,此篇我們來用比較原始的方法,使用的是Android內部的拍照功能
相對也比較複雜一點,使用的時機是客製化比較重而呼叫其他拍照應用程式也無法完成的
這時就必須用到原始的方法,直接用內部拍照預覽功能了,開始為您介紹
使用之前,因為調用照相功能有權限問題,所以必須在AndroidManifest.xml內加入照相權限
及相關我們需要用到的自動對焦功能
//拍照權限
<uses-permission android:name="android.permission.CAMERA" />
//自動對焦
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
//螢幕轉為橫向顯示,因為預設為橫向拍照,如果不設計成橫向
//預覽畫面和拍出來的照片會自動轉90度
android:screenOrientation="landscape"
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="jim.camera" android:versionCode="1" android:versionName="1.0" android:installLocation="auto"> <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="8"/> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".CameraActivity" android:label="@string/app_name" android:screenOrientation="landscape" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:weightSum="1"> <LinearLayout android:layout_height="wrap_content" android:id="@+id/linearLayout1" android:layout_width="fill_parent"> <SurfaceView android:id="@+id/surfaceView1" android:layout_width="250dp" android:layout_height="250dp" /> <Button android:text="拍照" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button> <ImageView android:id="@+id/imageView1" android:layout_width="250dp" android:layout_height="250dp" /> </LinearLayout> </LinearLayout>
CameraActivity.java
package jim.camera; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import android.app.Activity; 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.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class CameraActivity extends Activity implements SurfaceHolder.Callback{ SurfaceHolder surfaceHolder; SurfaceView surfaceView1; Button button1; ImageView imageView1; Camera camera; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button1=(Button)findViewById(R.id.button1); //在AndroidManifest.xml中設定或是用下面的setRequestedOrientation(0)設定也可以 //0代表橫向、1代表縱向 setRequestedOrientation(0); //設為横向顯示。因為攝影頭會自動翻轉90度,所以如果不横向顯示,看到的畫面就是翻轉的。 surfaceView1=(SurfaceView)findViewById(R.id.surfaceView1); imageView1=(ImageView)findViewById(R.id.imageView1); surfaceHolder=surfaceView1.getHolder(); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); surfaceHolder.addCallback(this); button1.setOnClickListener(new OnClickListener(){ public void onClick(View v) { //自動對焦 camera.autoFocus(afcb); }}); } PictureCallback jpeg =new PictureCallback(){ public void onPictureTaken(byte[] data, Camera camera) { Bitmap bmp=BitmapFactory.decodeByteArray(data, 0, data.length); //byte數组轉換成Bitmap imageView1.setImageBitmap(bmp); //拍下圖片顯示在下面的ImageView裡 FileOutputStream fop; try { fop=new FileOutputStream("/sdcard/dd.jpg"); //實例化FileOutputStream,參數是生成路徑 bmp.compress(Bitmap.CompressFormat.JPEG, 100, fop); //壓缩bitmap寫進outputStream 參數:輸出格式 輸出質量 目標OutputStream //格式可以為jpg,png,jpg不能存儲透明 fop.close(); System.out.println("拍照成功"); //關閉流 } catch (FileNotFoundException e) { e.printStackTrace(); System.out.println("FileNotFoundException"); } catch (IOException e) { e.printStackTrace(); System.out.println("IOException"); } camera.startPreview(); //需要手動重新startPreview,否則停在拍下的瞬間 } }; public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } public void surfaceCreated(SurfaceHolder holder) { camera=Camera.open(); try { Camera.Parameters parameters=camera.getParameters(); parameters.setPictureFormat(PixelFormat.JPEG); parameters.setPreviewSize(320, 220); camera.setParameters(parameters); //設置參數 camera.setPreviewDisplay(surfaceHolder); //鏡頭的方向和手機相差90度,所以要轉向 //camera.setDisplayOrientation(90); //攝影頭畫面顯示在Surface上 camera.startPreview(); } catch (IOException e) { e.printStackTrace(); } } public void surfaceDestroyed(SurfaceHolder holder) { System.out.println("surfaceDestroyed"); camera.stopPreview(); //關閉預覽 camera.release(); // } //自動對焦監聽式 AutoFocusCallback afcb= new AutoFocusCallback(){ public void onAutoFocus(boolean success, Camera camera) { if(success){ //對焦成功才拍照 camera.takePicture(null, null, jpeg); } } }; }
執行後畫面
說明:
1.Android的照相功能預計是橫向拍照,所以如果您是用直立的方式拍照
您就需要把預覽畫面轉向90度在surfaceCreated方法中加入camera.setDisplayOrientation(90);
預覽畫面就會轉90度,再來把得到的照片也要轉90度,不然得到的照片還是會是轉了90度
這方面可以自行實驗一下就會大概知道它的原理了。
public class CameraActivity extends Activity implements SurfaceHolder.Callback
2.相機功能除了繼承Activity之外,也需要實現SurfaceHolder.Callback這個預覽界面接口
用來接收攝影鏡頭預覽界面變化的訊息,它有三個方法:
(1)surfaceCreated:當預覽界面創建時調用此方法
(2)surfaceChanged:當預覽界面的格式和大小改變時調用此方法
(3)surfaceDestroyed:當預覽界面被關閉時調用此方法
3.照相的流程大概是:
(1)在佈局檔main.xml中會有一個SurfaceView
(2)加入surfaceHolder以控制隨時在變動的SurfaceView
(3)創始應用程式時觸發surfaceCreated,開啟攝影鏡頭及設定相關參數(相片格式及尺寸)
攝影頭畫面顯示在 SurfaceView 上
(4)Button內的onClick事件中使用自動對焦camera.autoFocus(afcb);
(5)自動對焦監聽式AutoFocusCallback afcb= new AutoFocusCallback()
對焦成功才會調用camera.takePicture(null, null, jpeg);拍照
(6)得到的照片進入PictureCallback jpeg =new PictureCallback()處理
(7)完成關閉程式時會觸發surfaceDestroyed關閉預覽及釋放資源
後記:
本人在使用上是比較習慣直接用Intent呼叫其它拍照服務的方法在做
除非呼叫的方法不能達到我想要的目的,我才會想要用這個方法做,不然這個方法
是比較麻煩的,因為看程式碼和說明也知道,比上一篇複雜上很多倍,以上就是為
您介紹使用內部照相功能,有問題請留言或來信告知,感謝。
我弄下來測試發現,沒錯誤但不能執行
回覆刪除方便給我原始檔案嗎?
我也不能執行 能給原始檔嗎?
回覆刪除這是有縮圖的作法, 如何做到原圖儲存?
回覆刪除移除parameters.setPreviewSize(320, 220); 就可以執行了
回覆刪除