Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android多媒體學習三:實現自己的Camera

Android多媒體學習三:實現自己的Camera

編輯:Android開發實例

Android自帶的Camera應用雖然可以滿足大多數情景,但是其靈活性上還有不足。但是Android允許我們定制自己的Camera。

在Android的hardware包中有一個Camera類。這個類就是獲取Camera服務的,可以定制Camera等。

可以通過open()方法獲取其實例。

在使用這個類是需要在AndroidManifest.xml文件中加入相應的權限和特性

如:

  <uses-permission android:name = "android.permission.CAMERA" />
  <uses-feature android:name = "android.hardware.camera" />
  <uses-feature android:name = "android.hardware.camera.autofocus" />


等。

本文實例:

 

  1. package demo.camera;  
  2. import java.io.OutputStream;  
  3. import java.util.Iterator;  
  4. import java.util.List;  
  5. import android.app.Activity;  
  6. import android.content.ContentValues;  
  7. import android.content.res.Configuration;  
  8. import android.hardware.Camera;  
  9. import android.net.Uri;  
  10. import android.os.Bundle;  
  11. import android.provider.MediaStore;  
  12. import android.view.SurfaceHolder;  
  13. import android.view.SurfaceView;  
  14. import android.view.View;  
  15. import android.widget.LinearLayout;  
  16. /**  
  17.  * Android自帶的Camera應用程序可以完成很多功能。但是當其不能滿足我們需要的時候  
  18.  * 我們可以定制自己的Camera。Android提供了Camera類來輔助我們實現自己的Camera。  
  19.  * 這個例子就來定義一個自己的Camera  
  20.  * 首先,在Manifest中需要引入權限<uses-permission android:name="android:permission.CAMERA"/>  
  21.  * 我們需要用來存放取景器的容器,這個容器就是SurfaceView。  
  22.  * 使用SurfaceView的同時,我們還需要使用到SurfaceHolder,SurfaceHolder相當於一個監聽器,可以監聽  
  23.  * Surface上的變化,通過其內部類CallBack來實現。  
  24.  * 為了可以獲取圖片,我們需要使用Camera的takePicture方法同時我們需要實現Camera.PictureCallBack類,實現onPictureTaken方法  
  25.  * @author Administrator  
  26.  *  
  27.  */ 
  28. public class MyCamera extends Activity implements SurfaceHolder.Callback,Camera.PictureCallback{  
  29.       
  30.     public static final int MAX_WIDTH = 200;  
  31.     public static final int MAX_HEIGHT = 200;  
  32.       
  33.     private SurfaceView surfaceView;  
  34.       
  35.     private Camera camera; //這個是hardare的Camera對象  
  36.       
  37.     public void onCreate(Bundle savedInstanceState){  
  38.         super.onCreate(savedInstanceState);  
  39.         this.setContentView(R.layout.camera);  
  40.         surfaceView = (SurfaceView)this.findViewById(R.id.myCameraView);  
  41.         surfaceView.setFocusable(true);   
  42.         surfaceView.setFocusableInTouchMode(true);  
  43.         surfaceView.setClickable(true);  
  44.         surfaceView.setOnClickListener(new View.OnClickListener() {  
  45.               
  46.             @Override 
  47.             public void onClick(View v) {  
  48.                   
  49.                 camera.takePicture(null, null, null, MyCamera.this);  
  50.                   
  51.             }  
  52.         });  
  53.         //SurfaceView中的getHolder方法可以獲取到一個SurfaceHolder實例  
  54.         SurfaceHolder holder = surfaceView.getHolder();  
  55.         //為了實現照片預覽功能,需要將SurfaceHolder的類型設置為PUSH  
  56.         //這樣,畫圖緩存就由Camera類來管理,畫圖緩存是獨立於Surface的  
  57.         holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
  58.         holder.addCallback(this);  
  59.     }  
  60.     @Override 
  61.     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {  
  62.     }  
  63.     @Override 
  64.     public void surfaceCreated(SurfaceHolder holder) {  
  65.         // 當Surface被創建的時候,該方法被調用,可以在這裡實例化Camera對象  
  66.         //同時可以對Camera進行定制  
  67.         camera = Camera.open(); //獲取Camera實例  
  68.       
  69.           
  70.         /**  
  71.          * Camera對象中含有一個內部類Camera.Parameters.該類可以對Camera的特性進行定制  
  72.          * 在Parameters中設置完成後,需要調用Camera.setParameters()方法,相應的設置才會生效  
  73.          * 由於不同的設備,Camera的特性是不同的,所以在設置時,需要首先判斷設備對應的特性,再加以設置  
  74.          * 比如在調用setEffects之前最好先調用getSupportedColorEffects。如果設備不支持顏色特性,那麼該方法將  
  75.          * 返回一個null  
  76.          */ 
  77.         try {  
  78.               
  79.             Camera.Parameters param = camera.getParameters();  
  80.             if(this.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){  
  81.                 //如果是豎屏  
  82.                 param.set("orientation", "portrait");  
  83.                 //在2.2以上可以使用  
  84.                 //camera.setDisplayOrientation(90);  
  85.             }else{  
  86.                 param.set("orientation", "landscape");  
  87.                 //在2.2以上可以使用  
  88.                 //camera.setDisplayOrientation(0);                
  89.             }  
  90.             //首先獲取系統設備支持的所有顏色特效,有復合我們的,則設置;否則不設置  
  91.             List<String> colorEffects = param.getSupportedColorEffects();  
  92.             Iterator<String> colorItor = colorEffects.iterator();  
  93.             while(colorItor.hasNext()){  
  94.                 String currColor = colorItor.next();  
  95.                 if(currColor.equals(Camera.Parameters.EFFECT_SOLARIZE)){  
  96.                     param.setColorEffect(Camera.Parameters.EFFECT_SOLARIZE);  
  97.                     break;  
  98.                 }  
  99.             }  
  100.             //設置完成需要再次調用setParameter方法才能生效  
  101.             camera.setParameters(param);  
  102.               
  103.             camera.setPreviewDisplay(holder);  
  104.               
  105.             /**  
  106.              * 在顯示了預覽後,我們有時候希望限制預覽的Size  
  107.              * 我們並不是自己指定一個SIze而是指定一個Size,然後  
  108.              * 獲取系統支持的SIZE,然後選擇一個比指定SIZE小且最接近所指定SIZE的一個  
  109.              * Camera.Size對象就是該SIZE。  
  110.              *   
  111.              */ 
  112.             int bestWidth = 0;  
  113.             int bestHeight = 0;  
  114.               
  115.             List<Camera.Size> sizeList = param.getSupportedPreviewSizes();  
  116.             //如果sizeList只有一個我們也沒有必要做什麼了,因為就他一個別無選擇  
  117.             if(sizeList.size() > 1){  
  118.                 Iterator<Camera.Size> itor = sizeList.iterator();  
  119.                 while(itor.hasNext()){  
  120.                     Camera.Size cur = itor.next();  
  121.                     if(cur.width > bestWidth && cur.height>bestHeight && cur.width <MAX_WIDTH && cur.height < MAX_HEIGHT){  
  122.                         bestWidth = cur.width;  
  123.                         bestHeight = cur.height;  
  124.                     }  
  125.                 }  
  126.                 if(bestWidth != 0 && bestHeight != 0){  
  127.                     param.setPreviewSize(bestWidth, bestHeight);  
  128.                     //這裡改變了SIze後,我們還要告訴SurfaceView,否則,Surface將不會改變大小,進入Camera的圖像將質量很差  
  129.                     surfaceView.setLayoutParams(new LinearLayout.LayoutParams(bestWidth, bestHeight));  
  130.                 }  
  131.             }  
  132.             camera.setParameters(param);  
  133.         } catch (Exception e) {  
  134.             // 如果出現異常,則釋放Camera對象  
  135.             camera.release();  
  136.         }  
  137.           
  138.         //啟動預覽功能  
  139.         camera.startPreview();  
  140.           
  141.     }  
  142.     @Override 
  143.     public void surfaceDestroyed(SurfaceHolder holder) {  
  144.         // 當Surface被銷毀的時候,該方法被調用  
  145.         //在這裡需要釋放Camera資源  
  146.         camera.stopPreview();  
  147.         camera.release();  
  148.           
  149.     }  
  150.     @Override 
  151.     public void onPictureTaken(byte[] data, Camera camera) {  
  152.         // data是一個原始的JPEG圖像數據,  
  153.         //在這裡我們可以存儲圖片,很顯然可以采用MediaStore  
  154.         //注意保存圖片後,再次調用startPreview()回到預覽  
  155.         Uri imageUri = this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());  
  156.         try {  
  157.             OutputStream os = this.getContentResolver().openOutputStream(imageUri);  
  158.             os.write(data);  
  159.             os.flush();  
  160.             os.close();  
  161.         } catch (Exception e) {  
  162.             // TODO: handle exception  
  163.             e.printStackTrace();  
  164.         }  
  165.           
  166.         camera.startPreview();  
  167.     }  
  168.       
  169.       
  170.       
  171. }  
  172.  

 

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