1. 程式人生 > >Android呼叫Camera,獲取預覽幀中的影象

Android呼叫Camera,獲取預覽幀中的影象

轉載自http://blog.csdn.net/u013869488/article/details/49853217

1:說明
Android開發實現Camera自定義的話,也並不是件難事,主要步驟如下:

  • 開啟相機,即例項化Camera物件,Camera camera = Camera.open();
  • 設定Camera的相關引數,Camera.Parameters parameters = camera.getParameters();
  • 開啟預覽,camera.setPreviewDisplay(surfaceholder); camera.startPreview();
  • 獲取圖片,這裡只是從預覽中獲取因此使用,camera.setPreviewCallback(new Camera.PreviewCallback(){……..});
  • 停止預覽,釋放相機,camera.stopPreview();camera.release();

2:那麼問題來了,僅僅這樣就行了嗎?
當然,我們還需要顯示Camera預覽的影象的地方。因此需要一個叫做SurfaceView的控制元件,和一個用來控制顯示的SurfaceHolder的東西。步驟如下:

  • 定義SurfaceView控制元件; SurfaceView mySurfaceView = (SurfaceView)findViewById(R.id.id_mySurfaceView);
  • 例項化SurfaceHolder,這個是實現預覽處理的地方,相機開啟預覽的時候要設定camera.setPreviewDisplay(surfaceholder); 表明在SurfaceHolder 上面實現預覽。當然例項化是這樣實現的:SurfaceHolder surfaceHolder = mySurfaceView .getHolder();
  • 給SurfaceHolder設定回撥,也就是類似於監聽,只不過它主要是監聽Camera的相關狀態;surfaceHolder.addCallback(this);
  • 實現SurfaceHolder.Callback介面,類似於定於監聽就要實現相對應的監聽介面。然後就會有三個方法要實現。

3:詳細講解SurfaceHolder.Callback介面對應的三個函式:
(1) surfaceCreated方法:

@Override
    public void surfaceCreated(SurfaceHolder holder) {
    //一般在這裡實現相機開啟
    //相機在這裡設定相關引數也是可以的
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(2)surfaceChanged方法:

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
//在這裡也可以設定Camera的引數
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(3)surfaceDestroyed方法:

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    //主要在這裡實現Camera的釋放
        if (camera!=null) {
            camera.release();
            camera=null;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

4:在哪裡獲取圖片呢?
這要是我們的主要任務,不獲取圖片貌似我們也沒有必要開啟相機哈。
可以定義一個按鈕來獲取圖片,呼叫獲取圖片的方法不就好了嘛,那麼就開始獲取預覽幀圖片的獲取的方法吧:

private void getPreViewImage() {

camera.setPreviewCallback(new Camera.PreviewCallback(){

@Override
public void onPreviewFrame(byte[] data, Camera camera) {
 Size size = camera.getParameters().getPreviewSize();          
 try{  
     YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);  
     if(image!=null){  
                     ByteArrayOutputStream stream = new ByteArrayOutputStream();  
                    image.compressToJpeg(new Rect(0, 0, size.width, size.height), 80, stream); 

                   Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());  

                    //**********************
                    //因為圖片會放生旋轉,因此要對圖片進行旋轉到和手機在一個方向上
                    rotateMyBitmap(bmp);
                    //**********************************

         stream.close();  
    }  
 }catch(Exception ex){  
  Log.e("Sys","Error:"+ex.getMessage());  
  }  
}   
});
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

這裡就是圖片旋轉函式:

public void rotateMyBitmap(Bitmap bmp){
  //*****旋轉一下
Matrix matrix = new Matrix();
 matrix.postRotate(90);

 Bitmap bitmap = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.ARGB_8888);

Bitmap nbmp2 = Bitmap.createBitmap(bmp, 0,0, bmp.getWidth(),  bmp.getHeight(), matrix, true);

//*******顯示一下
imageView.setImageBitmap(nbmp2);

};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

5:到此好像圖片的預覽幀獲取也就實現了。
但是還有幾個問題:
(1)Camera的引數設定:

public void initCamera(){
//CameraID表示0或者1,表示是前置攝像頭還是後置攝像頭
camera = Camera.open(CameraID);
camera.setDisplayOrientation(90);
//引數設定
Camera.Parameters parameters = camera.getParameters();
//設定放大倍數
parameters.setZoom(12);
//開啟閃光燈         parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); 
//引數設定賦給Camera物件
camera.setParameters(parameters);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

(2)獲取預覽幀問題
camera.setPreviewCallback(new Camera.PreviewCallback(){……..});
獲取的預覽幀就是攝像頭實時獲取的影象,而實際上我只是想線割一秒中獲取一張圖片而已,因此設定了

    Handler handle = new Handler(){ 
        public void handleMessage(android.os.Message msg) {
            switch(msg.what){

            case BUFFERTAG:
                if(isGetBuffer){
                    getPreViewImage();
                    btnGetBuffer.setText("開始圖片1");
                    handler.sendEmptyMessageDelayed(BUFFERTAG1, 300);

                }else{
                    camera.setPreviewCallback(null);
                }
                break;
            case BUFFERTAG1:
                camera.setPreviewCallback(null);
                handler.sendEmptyMessageDelayed(BUFFERTAG, 5000);
                break ;


            }

        };
        };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

(3)切換攝像頭的時候
首先將已經存在的攝像頭釋放,然後再重新開啟就可以了;
(4)關閉閃光燈的問題
就是設定Camera的對應的引數重新設定一遍就可以了。

            Camera.Parameters parameters = camera.getParameters();

            //開啟閃光燈
            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH); 
    //關閉攝像頭  //parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); 
            camera.setParameters(parameters);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

6:結束
到這裡,就可以實現選擇性的獲取攝像頭的預覽幀的圖片了。

相關推薦

Android呼叫Camera獲取影象

轉載自http://blog.csdn.net/u013869488/article/details/49853217 1:說明 Android開發實現Camera自定義的話,也並不是件難事,主要步驟如下: 開啟相機,即例項化Camera物件,Camera camera = Camera.open();設定

android 呼叫Camera獲取影象

1:說明 android開發實現Camera自定義的話,也並不是件難事,主要步驟如下: 開啟相機,即例項化Camera物件,Camera camera = Camera.open(); 設定Camera的相關引數,Camera.Parameters par

視訊播放surfaceView camera獲取影象顯示setPreviewCallback()

同事找我做一個視訊預覽複製,實現螢幕一分為二,同時顯示相同畫面。這裡寫個demo版 本篇的重點是 camera.setPreviewCallback() 在視訊預覽過程中,每一幀的影象資料均會通過這個callback返回,在這裡面我們可以處理返回的位元組陣列,轉換為b

(一)Android camera2 實現相機獲取資料流

一、本文重點說明 本文基於 android camera2 實現視訊預覽,暫未相容 camera1 API,基礎實現可以參考 googlesample Camera2 例子 android-Camera2Basic ,本文以工具類形式實現一步呼叫。 谷歌例子中沒有具體指

玩轉Android Camera開發 四 介面四周暗中間亮只拍攝矩形區域圖片 附完整原始碼

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Android Camera 自動適配多種螢幕解決照片拉伸和儲存的圖片拉伸

最近公司需要做一個手機自拍照的功能,由於之前有做過類似手機拍照的功能,所以很快就實現了自定義手機拍的功能。但是後面發現部分手機出現預覽照片拉伸和儲存的圖片拉伸的情況。然後百度了一下,發現原理很好理解,也有一堆demo,然而並沒有解決拉伸的情況。下面總結一下我的解決方法,希望對

Android相機不使用SurfaceView使用ImageView

剛接觸Android三個月,以下內容可能存在錯誤,歡迎指正。 以下在Android5. 1 ,API22機器下除錯的。 之前參考網上的資源,很多使用的surfaceView控制元件預覽相機,所以就用的是surfaceview。但是我的需求不僅是預覽,還需要經常性的拍照,然後在程式碼裡處理圖片

android獲取圖片原始長寬獲取視訊第一的縮圖

public static Bitmap getVideoThumbnail(String videoPath) { MediaMetadataRetriever media =new MediaMetadataRetriever(); media.setDataSource(videoPat

AndroidCamera過程插拔攝像頭節點後移

現象: 在使用Camera Preview時;熱插拔攝像頭會導致裝置節點由/dev/video0變為/dev/video1,或者插入多個video裝置時,會變為/dev/video1、/dev/video2......。 一、首先看裝置節點的建立 drivers/media

Android實時監控專案第三篇:通過攝像頭實時視訊

在第二個Activity中,我們要顯示攝像頭預覽的視訊,佈局檔案很簡單,就一個SurfaceView元件,設定為佔滿整個父元件(這裡不再給出),用來顯示預覽的視訊。       在對應的Activity檔案中,要獲取SurfaceView的SurfaceHolder,併

Android 超高仿微信圖片多選、單選圖片剪下圖片拍照等功能

實現了微信圖片選擇的所有功能 單選、多選 單選,沒有預覽功能。 多選,可以控制最大 選擇圖片數量 拍照 解決了三星拍照橫屏的bug 關閉拍照後,第一個item將不顯示拍照選項 預覽 開啟預覽功能後,點選圖片或右下角預覽進入預覽介面。 關

Android使用Camera2獲取資料

一、Camera2簡介 Camera2是Google在Android 5.0後推出的一個全新的相機API,Camera2和Camera沒有繼承關係,是完全重新設計的,且Camera2支援的功能也更加豐富,但是提供了更豐富的功能的同時也增加了使用的難度。Google的官方Demo:https://gith

springmvc圖片上傳(兼容ie8以上實時

處理 spa aps news time htm tip 技術分享 ans html代碼: <form id="uploadform" method="post" enctype="multipart/form-data"> <

WebForm實現文件上傳

image form ict itl lec nbsp style object 是否 實現效果: 頁面代碼: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inh

Android Studio 第七十四期 - Android 新浪大圖

microsoft span androi http and 微軟雅黑 git sina bsp 代碼已經整理好,效果如下圖: 地址:https://github.com/geeklx/myapplication2018/tree/master/p01

我也不知道這算不算bug了單純記錄沒別的意思圖片是上傳在慕課網的所以不了。。0.0

。。 https ref 讓我 chrom ron 允許 error 個人 無意發現慕課網修改個人簽名功能性bug 修改個人簽名失敗的問題 圖片 經過測試,像這樣兩行文字中間有換行的話,保存會提示error,如圖: 圖片 而如果不換行,就能成功: 圖片 圖片 瀏覽器用的Ch

Android Studio xml檔案無法

版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://mp.csdn.net/postedit 更新as到3.0.1後 佈局檔案的Design無法預覽佈局,顯示空白 在網上找到個辦法: 修改res/values/styles.xml檔案中name=“AppTheme”的s

使用JCrop進行圖片裁剪裁剪js說明裁剪裁剪上傳裁剪設計的圖片處理的工具類和程式碼

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Android studio xml介面無法問題

Android studio xml介面無法預覽問題 如下圖 修改style.xml中的 parent=“Theme.AppCompat.Light.DarkActionBar” 改為 parent=“Base.Theme.AppCompat.Light.DarkActionBar”

Java開發公眾號系列教程(三):微信js-sdk多圖片上傳支援刪除

用過微信的人都知道,日常發表朋友圈圖文動態時,可以選擇多圖片,圖片右上角有個灰色的刪除圖示,可以對即將要發表的照片資訊進行預覽和刪除。今天筆者通過微信js-sdk介面給大家把這個實現過程分享出來。 一、主體思路 微信js-sdk上傳介面支援單次最多選擇9張圖片,我們要實現的就是跟微