Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android學習指南之三十六:Android手機攝像頭開發初步

Android學習指南之三十六:Android手機攝像頭開發初步

編輯:關於android開發

       智能手機中的攝像頭和普通手機中的攝像頭最大的區別在於,智能機上的攝像頭可以由程序員寫程序控制,做一些有趣的應用譬如,畫中畫,做一些有用的應用譬如二維碼識別,等等。本講打算通過一個實例,來介紹一下攝像頭編程,相關解釋都寫在代碼中了,請注意看代碼注釋。

       實例:窈窈照相機,功能很簡單,就是點擊程序彈出照相預覽界面,點擊相機按鈕完成照相功能,所照相片會存儲在手機存儲卡根目錄。

       1、創建一個項目 Lesson36_Camera ,主程序文件為 MainActivity.java。

       2、AndroidManifest.xml 中設置屏幕為橫屏,並且聲明攝像頭和存儲卡的使用權限,具體代碼如下:

XML/HTML代碼
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <MANIFEST android:versionname="1.0" android:versioncode="1" xmlns:android="http://schemas.android.com/apk/res/android" package="basic.android.lesson36">  
  3.     <APPLICATION android:icon="@drawable/icon" android:label="@string/app_name">  
  4.         <ACTIVITY android:name=".MainActivity" android:label="@string/app_name" android:configchanges="orientation|keyboardHidden|keyboard" android:screenorientation="landscape">  
  5.             <INTENT -filter>  
  6.                 <ACTION android:name="android.intent.action.MAIN" />  
  7.                 <CATEGORY android:name="android.intent.category.LAUNCHER" />  
  8.             </INTENT>  
  9.         </ACTIVITY>  
  10.   
  11.     </APPLICATION>  
  12.     <USES android:minsdkversion="8" -sdk />  
  13.     <USES android:name="android.permission.CAMERA" -permission></USES>  
  14.     <USES android:name="android.permission.WRITE_EXTERNAL_STORAGE" -permission></USES>  
  15.     <USES android:name="android.hardware.camera" -feature />  
  16.     <USES android:name="android.hardware.camera.autofocus" -feature />  
  17. </MANIFEST>    

       3、本例中不需要布局文件main.xml,因為本例中的UI組建都是動態添加上去的。

       4、最後MainActivity.java的代碼如下:

Java代碼
  1. package basic.android.lesson36;   
  2.   
  3. import java.io.BufferedOutputStream;   
  4. import java.io.File;   
  5. import java.io.FileOutputStream;   
  6. import java.io.IOException;   
  7. import java.util.Calendar;   
  8. import java.util.Locale;   
  9.   
  10. import android.app.Activity;   
  11. import android.content.Context;   
  12. import android.graphics.Bitmap;   
  13. import android.graphics.BitmapFactory;   
  14. import android.graphics.PixelFormat;   
  15. import android.hardware.Camera;   
  16. import android.os.Bundle;   
  17. import android.text.format.DateFormat;   
  18. import android.util.Log;   
  19. import android.view.KeyEvent;   
  20. import android.view.SurfaceHolder;   
  21. import android.view.SurfaceView;   
  22. import android.view.Window;   
  23. import android.view.WindowManager;   
  24. import android.widget.FrameLayout;   
  25. import android.widget.TextView;   
  26. import android.widget.Toast;   
  27.   
  28. public class MainActivity extends Activity {   
  29.   
  30.     private CameraView cv;   
  31.     //准備一個相機對象   
  32.     private Camera mCamera = null;   
  33.     //准備一個Bitmap對象   
  34.     private Bitmap mBitmap = null;     
  35.   
  36.     //准備一個保存圖片的PictureCallback對象   
  37.     public Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {   
  38.   
  39.         public void onPictureTaken(byte[] data, Camera camera) {   
  40.             Log.i("yao","onPictureTaken");   
  41.             Toast.makeText(getApplicationContext(), "正在保存……", Toast.LENGTH_LONG).show();   
  42.             //用BitmapFactory.decodeByteArray()方法可以把相機傳回的裸數據轉換成Bitmap對象   
  43.             mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);   
  44.             //接下來的工作就是把Bitmap保存成一個存儲卡中的文件   
  45.             File file = new File("/sdcard/YY"+ new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg");   
  46.             try {   
  47.                 file.createNewFile();   
  48.                 BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file));   
  49.                 mBitmap.compress(Bitmap.CompressFormat.PNG, 100, os);   
  50.                 os.flush();   
  51.                 os.close();   
  52.                 Toast.makeText(getApplicationContext(), "圖片保存完畢,在存儲卡的根目錄", Toast.LENGTH_LONG).show();   
  53.             } catch (IOException e) {   
  54.                 e.printStackTrace();   
  55.             }   
  56.         }   
  57.   
  58.     };   
  59.   
  60.     //Activity的創建方法   
  61.     @Override  
  62.     public void onCreate(Bundle savedInstanceState) {   
  63.         super.onCreate(savedInstanceState);   
  64.   
  65.         //窗口去掉標題   
  66.         requestWindowFeature(Window.FEATURE_NO_TITLE);   
  67.         //窗口設置為全屏   
  68.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);   
  69.         //設置窗口為半透明   
  70.         getWindow().setFormat(PixelFormat.TRANSLUCENT);   
  71.   
  72.         //提供一個幀布局   
  73.         FrameLayout  fl = new FrameLayout(this);         
  74.   
  75.         //創建一個照相預覽用的SurfaceView子類,並放在幀布局的底層   
  76.         cv = new CameraView(this);   
  77.         fl.addView(cv);   
  78.   
  79.         //創建一個文本框添加在幀布局中,我們可以看到,文字自動出現在了SurfaceView的前面,由此你可以在預覽窗口做出各種特殊效果   
  80.         TextView tv = new TextView(this);   
  81.         tv.setText("請按\"相機\"按鈕拍攝");   
  82.         fl.addView(tv);   
  83.   
  84.         //設置Activity的根內容視圖   
  85.         setContentView(fl);   
  86.   
  87.     }   
  88.   
  89.     //相機按鍵按下的事件處理方法   
  90.     public boolean onKeyDown(int keyCode, KeyEvent event) {   
  91.         Log.i("yao","MainActivity.onKeyDown");   
  92.         if (keyCode == KeyEvent.KEYCODE_CAMERA) {   
  93.             if (mCamera != null) {   
  94.                 Log.i("yao","mCamera.takePicture");   
  95.                 //當按下相機按鈕時,執行相機對象的takePicture()方法,該方法有三個回調對象做入參,不需要的時候可以設null   
  96.                 mCamera.takePicture(null, null, pictureCallback);   
  97.             }   
  98.         }   
  99.         return cv.onKeyDown(keyCode, event);   
  100.     }   
  101.   
  102.     // 照相視圖   
  103.     class CameraView extends SurfaceView {   
  104.   
  105.         private SurfaceHolder holder = null;   
  106.   
  107.         //構造函數   
  108.         public CameraView(Context context) {   
  109.             super(context);   
  110.             Log.i("yao","CameraView");   
  111.   
  112.             // 操作surface的holder   
  113.             holder = this.getHolder();   
  114.             // 創建SurfaceHolder.Callback對象   
  115.             holder.addCallback(new SurfaceHolder.Callback() {   
  116.   
  117.                 @Override  
  118.                 public void surfaceDestroyed(SurfaceHolder holder) {   
  119.                     // 停止預覽   
  120.                     mCamera.stopPreview();   
  121.                     // 釋放相機資源並置空   
  122.                     mCamera.release();   
  123.                     mCamera = null;   
  124.                 }   
  125.   
  126.                 @Override  
  127.                 public void surfaceCreated(SurfaceHolder holder) {   
  128.                     //當預覽視圖創建的時候開啟相機   
  129.                     mCamera = Camera.open();   
  130.                     try {   
  131.                         //設置預覽   
  132.                         mCamera.setPreviewDisplay(holder);   
  133.                     } catch (IOException e) {   
  134.                         // 釋放相機資源並置空   
  135.                         mCamera.release();   
  136.                         mCamera = null;   
  137.                     }   
  138.   
  139.                 }   
  140.   
  141.                 //當surface視圖數據發生變化時,處理預覽信息   
  142.                 @Override  
  143.                 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {   
  144.   
  145.                     //獲得相機參數對象   
  146.                     Camera.Parameters parameters = mCamera.getParameters();   
  147.                     //設置格式   
  148.                     parameters.setPictureFormat(PixelFormat.JPEG);   
  149.                     //設置預覽大小,這裡我的測試機是Milsstone所以設置的是854x480   
  150.                     parameters.setPreviewSize(854, 480);   
  151.                     //設置自動對焦   
  152.                     parameters.setFocusMode("auto");   
  153.                     //設置圖片保存時的分辨率大小   
  154.                     parameters.setPictureSize(2592, 1456);   
  155.                     //給相機對象設置剛才設定的參數   
  156.                     mCamera.setParameters(parameters);   
  157.                     //開始預覽   
  158.                     mCamera.startPreview();   
  159.                 }   
  160.             });   
  161.             // 設置Push緩沖類型,說明surface數據由其他來源提供,而不是用自己的Canvas來繪圖,在這裡是由攝像頭來提供數據   
  162.             holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);   
  163.         }   
  164.   
  165.     }   
  166.   
  167. }  

       5、連接Milestone,編譯並運行程序:悲劇的是,截圖只能看到黑黑的一片,無法截取到攝像頭傳輸過來SurfaceView信息,而在真機中是能看到預覽效果的。

Android學習指南之三十六:Android手機攝像頭開發初步

       還是上一張照好的圖片給大家吧,(用了好多年的小黑……)

Android學習指南之三十六:Android手機攝像頭開發初步

       好了,本講就到這裡,謝謝大家的支持和鼓勵,下次再見。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved