1. 程式人生 > >android相機對焦

android相機對焦

1、利用硬體感測器去實現自動對焦

註冊感測器:

SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);

感測器介面:

implements SensorEventListener

實現感測器介面方法:

 public void onSensorChanged(SensorEvent event) {
        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];
        if (initFirstSensor) {//初始化預設進入時候的座標
            mLastX = x;
            mLastY = y;
            mLastZ = z;
            initFirstSensor = false;
            return;
        }

        float deltaX = Math.abs(mLastX - x);
        float deltaY = Math.abs(mLastY - y);
        float deltaZ = Math.abs(mLastZ - z);

        if (deltaX > 2.5 || deltaY > 2.5 || deltaZ > 2.5) {//計算座標偏移值
            if (!isPhoto && mCamera != null) {
                playFocusAnimal(focusX, focusY);//播放對焦動畫             
                // mCamera.autoFocus(autoFocusCallback);//呼叫相機對焦
            }
        } 
        mLastX = x; 
        mLastY = y; 
        mLastZ = z; 
    }


2、單點觸控對焦

監聽touch事件拿到event:

 public boolean onTouch(View v, MotionEvent event) {
                if (!isPhoto && mCamera != null) {
                    playFocusAnimal((int) event.getX(), (int) event.getY());
                    touchFocus(event);
                }
                return false;
            }

根據觸控位置設定對焦點的對焦權值:

(解釋一下:每個對焦區域是一個具有特定權值的長方形。方向與重力感應的方向有關。而且不會受到 setDisplayOrientation(int)旋轉畫面設定的影響。矩形的座標範圍指定從-1000到1000 ,(-1000,-1000)是左上角點(1000,1000)是右下角點。對焦權值的取值範圍是1-1000,權值為矩形範圍畫素所平分,這意味著同樣的權值對焦區域大的對整體的對焦影響小。

理論結合實際的說就是,假如你的整個螢幕的寬度是width,那麼點選某個位置算x,那麼要劃定對焦區域,就要告訴相機對焦的座標,根據對焦座標的範圍為-1000到1000,所以要用公式計算對應的對焦座標實際上是: x/width*2000-1000=對焦x座標,同樣獲取到對焦y座標,然後以x,y為中心,指定對焦區域,設定對焦權值,越大表示優先對焦該位置)

程式碼:

 private void touchFocus(MotionEvent event) {
        mCamera.cancelAutoFocus();
        Camera.Parameters p = mCamera.getParameters();
        float touchX = (event.getRawX() / screenWidth) * 2000 - 1000;
        float touchY = (event.getRawY() / screenHeight) * 2000 - 1000;
        int left = clamp((int) touchX - AREA_SIZE / 2, -1000, 1000);
        int right = clamp(left + AREA_SIZE, -1000, 1000);
        int top = clamp((int) touchY - AREA_SIZE / 2, -1000, 1000);
        int bottom = clamp(top + AREA_SIZE, -1000, 1000);
        Rect rect = new Rect(left, top, right, bottom);
        if (p.getMaxNumFocusAreas() > 0) {
            List<Camera.Area> areaList = new ArrayList<Camera.Area>();
            areaList.add(new Camera.Area(rect, 1000));
            p.setFocusAreas(areaList);
        }
        if (p.getMaxNumMeteringAreas() > 0) {
            List<Camera.Area> areaList = new ArrayList<Camera.Area>();
            areaList.add(new Camera.Area(rect, 1000));
            p.setMeteringAreas(areaList);
        }
        p.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        try {
            mCamera.setParameters(p);
        } catch (Exception e) {

        }
        mCamera.autoFocus(autoFocusCallback);
    }

 private int clamp(int x, int min, int max) {//保證座標必須在min到max之內,否則異常
        if (x > max) {
            return max;
        }
        if (x < min) {
            return min;
        }
        return x;
    }


3、小米的坑

miui上的時候如果設定預覽解析度過高,則會導致拍照時候小米假死,無響應

解決方案:預覽解析度設定在螢幕解析度左右,對miui特殊對待

 private void initCameraParameters() {
        Camera.Parameters parameters = mCamera.getParameters();
        List<Camera.Size> vSizeList = parameters.getSupportedPictureSizes();
        Camera.Size showSize = null;
        Camera.Size tempSize;
        Camera.Size miuiSize = null;
        for (int num = 0; num < vSizeList.size(); num++) {
            tempSize = vSizeList.get(num);
            try {
                parameters.setPreviewSize(tempSize.width, tempSize.height);
                mCamera.setParameters(parameters);
                if (showSize == null || (showSize != null && tempSize.width > showSize.width)) {
                    showSize = tempSize;//設定最高可以支援的螢幕解析度
                }
                if (screenWidth < tempSize.width && (miuiSize == null || miuiSize.width > tempSize.width)) {
                    miuiSize = tempSize;//設定miui的預覽大小在螢幕解析度左右
                }
            } catch (Exception e) {

            }
            try {
                parameters.setPictureSize(tempSize.width, tempSize.height);
                mCamera.setParameters(parameters);
                if (highSize == null || (highSize != null && tempSize.width > highSize.width)) {
                    highSize = tempSize;//設定相機可支援的最高儲存解析度
                }
            } catch (Exception e) {

            }
            if (screenWidth > tempSize.width && (nomalSize == null || nomalSize.width < tempSize.width)) {
                nomalSize = tempSize;//設定一般相機儲存的解析度
            }
        }
        if (showSize != null) {
            if (android.os.Build.MANUFACTURER.equals("Xiaomi")) {//對待小米特殊設定
                parameters.setPreviewSize(miuiSize.width, miuiSize.height);
            } else {
                parameters.setPreviewSize(showSize.width, showSize.height);
            }
        }
        if (nomalSize != null) {
            parameters.setPictureSize(nomalSize.width, nomalSize.height);
            isNomal = true;
            if (picQualityButton != null) {
                picQualityButton.setImageDrawable(getResources().getDrawable(R.drawable.camera_pic_quality_nomal));
            }
        }
        if (isSupportFlash) {
            switch (currentFlashMode % 3) {
                case 0:
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                    break;
                case 1:
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                    break;
                case 2:
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
                    break;
            }
        } 
        parameters.setPictureFormat(PixelFormat.JPEG);
        parameters.setJpegQuality(100);
        mCamera.setParameters(parameters);
        mCamera.startPreview();
        playFocusAnimal(screenWidth / 2, screenHeight / 2);
        mCamera.autoFocus(autoFocusCallback);
    }

author:[email protected]

http://blog.csdn.net/iamws/article/details/50401886

相關推薦

android相機

1、利用硬體感測器去實現自動對焦 註冊感測器: SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE); sm.registerListener(this, sm.getDefaultSen

影象模糊度判斷方法--相機使用

在時域中,主要思路是考察影象的領域對比度,即相鄰畫素間的灰度特徵的梯度差,梯度函式常被用來提取邊緣資訊,聚焦良好的影象,具有更尖銳的邊緣,應有更大的梯度函式值。 在頻域中,主要思路是考察影象的頻率分量

Android camera2設定

在android camera2 api 開始,提供了對焦距值(非zoom值)的設定,大概步驟如下: (1)先關閉自動焦距模式    mPreviewBuilder.set(CaptureRequest.CONTROL_AE_MODE, CameraMetadata.CON

Android Camera相關

一、Camera 支援對焦模式簡介 在維護MTK Camera模組的時候,遇到Camera對焦的問題,Camera支援的對焦模式定義在frameworks/base/core/java/android/hardware/Camera.java下,主要有

Android自定義相機預覽開始時自動

      如果是呼叫系統相機不會存在對焦問題,要實現自己的相機在開始的時候自動自動對焦,只需要新增兩句程式碼:     parameters.setFocusMode(Camera.Paramet

android手動實現相機功能,自動+手動

android自定義相機實現自動對焦和手動對焦: 不呼叫系統相機,因為不同的機器開啟相機呈現的介面不統一也不能滿足需求。 所以為了讓程式在不同的機器上呈現出統一的介面,並且可以根據需求進行佈局,做了此demo。 程式實現程式碼如下: import java.io.File;

Android Camera2 拍照(四)——模式

ask als size com ontouch eating fault tdi release 原文:Android Camera2 拍照(四)——對焦模式 本

關於Android Camera2 API 的自動的坑

https://www.jianshu.com/p/280e5301b7b9 一、使用。關於Camera2的API使用,參考Google官方的例子: Camera2Basic Camera2Raw Camera2Video 這是一手資料,配合官方的資料理解Camera2 API的底層原理:

Android Camera高階特性——手動

Android Camera 系列目錄 1. 前言 對焦可以說是相機最基本的功能。 Android Camera提供了多種對焦方式: FOCUS_MODE_AUTO:個人認為這個名字起的有點隨意 FOCUS_MODE_CONTINUOUS_PICTURE :

Android 攝像頭自動的幾點注意

今天在做手機攝像頭自動對焦時出了一些問題,這裡做個筆記記錄一下。 注意事項:1、初始化Camera的程式碼中要加入下面兩行程式碼 mCamera.autoFocus(myAutoFocusCallback); mCamera.cancelAutoFocus(); 示例:

Android——呼叫攝像頭並自動拍…

import java.io.FileOutputStream; import android.content.Context; import android.hardware.Camera; import android.os.Environment; import android.view.Motion

[Android程式設計心得] Camera(OpenCV)自動和觸控的實現

import java.util.ArrayList; import java.util.List; import org.opencv.android.JavaCameraView; import android.R.integer; import android.content.Context; im

android實現自動拍照

android樣式和主題(style&theme) android中主題也是用於為應用定義顯示風格,它的定義和樣式的定義相同,如下: <?xmlversion="1.0" encoding="utf-8"?> <resources> <

Vuforia SDK---- AR開發vuforia 相機自動程式碼實現

在使用vuforia sdk製作AR時候有時候會遇到的問題就是相機不對焦,相機對著一個圖片時候在螢幕中顯示的非常不清晰,之前的文字中也介紹了AR的相機對焦功能。相機對焦文章,新版本4.x和3.x對焦程式碼不太一樣,比較簡單貼一下 3.x的 void Start () {

Android 使Camera預覽清晰,迴圈自動處理

我們經常使用SurfaceView顯示Camera預覽畫面,但畫面基本都不清晰。主要是因為沒有自動對焦,而自動對焦觸發是通過mCamera.autoFocus(autoFocusCallback);這個

Android 相機1 之Camera1的最簡單的使用(預覽、拍照、變、特效)

Android兩個相機的API的個人總結 API1的方法較少、命名規則等都比較簡單,如果是針對目前市面上的手機,API1是足夠而且使用起來非常方便,尤其是它的setParameter方法,相較於API2的要自己去填key和value來說,它不僅很容易能找到相機

如何實現android手機攝像頭的的自動

       發現好多人都在解決一個問題那就是,如何實現android相機的自動對焦,而且是連續自動對焦的。當然直接呼叫系統相機就不用說了,那個很簡單的。下面我們主要來看看如如何自己實現一個相機,並且實現自動連續對焦。      根據網上的資料有如下幾種:        

相機手動(帶動畫效果)

showsf_sv    = (SurfaceView)findViewById(R.id.camera_showsf_sv   ); // 成像控制元件 showsf_sv.setOnTouchListener(new TouchListener()); private

【Camera】手機相機自動的3種方式及原理

目前在手機上採用的自動對焦系統包括反差對焦、相位對焦和鐳射對焦三種方案。 反差對焦-CDAF(Contrast Detecti

帆軟發布大數據直連引擎FineDirect,大數據BI

finedirect 大數據 摘要:近日,帆軟官方正式發布大數據直連引擎FineDirect模塊。通過該模塊,企業在應用FineBI原有功能的基礎上,可直接對接現有數據源,無論是傳統的關系型數據庫,還是Hadoop生態圈、Mpp構架,都可以直接自助取數分析。當前,企業對數據的應用,一方面數據倉庫和BI