自定义相机自动对焦处理

示例图
首先提供几种参考方案:

第一:最常见的实现,利用按键或拍照前一次性自动聚焦在Activity里申明变量
private AutoFocusCallback myAutoFocusCallback = null;然后
自动聚焦变量回调

myAutoFocusCallback = new AutoFocusCallback()
{

public void onAutoFocus(boolean success, Camera
camera) {

// TODO Auto-generated method stub

}

};

在Camera.startPreview()之后,拍照Camera.takePicture()
之前调用myCamera.autoFocus(myAutoFocusCallback)

private final AutoFocusCallback autoFocusCallback = new AutoFocusCallback() {
    @Override
    public void onAutoFocus(boolean success, Camera camera) {
        //success表示对焦成功
        if (success){
            Log.i("TAG", "myAutoFocusCallback:success...");
            //myCamera.setOneShotPreviewCallback(null);
        } else {
            //未对焦成功
            Log.i("TAG", "myAutoFocusCallback: 失败了...");
        }
    }
};

第二:通过TimerTask设置一个定时器来循环,每隔一定时间调用myCamera.autoFocus(myAutoFocusCallback)一次。结果是摄像头一直在自我聚焦,重复清晰--模糊----清晰---模糊的过程。

第三:通过Handler和Thread,开启一个线程进行自动聚焦。本质和第二种是一样的。

第四:通过监听传感器来触发autoFocus。常用的是角度传感器或加速度传感器,当监听的值超过一定阈值时触发。这也是国外程序员们常用的思路。

第五:设置聚焦方式为myParam.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
意思是在录像的时候调用这种聚焦方式好,在拍照情况下这种聚焦方式可能不成功。
设置之后myParam.set("rotation", 90);
这句话的设置不起作用。拍摄得到的照片和预览的方向是错90度的。需要得到Bitmap之后,利用Matrix自己旋转下。
旋转示例:mBitmap = BitmapFactory.decodeByteArray(data, 0,
data.length);//data是字节数据,将其解析成位图myCamera.stopPreview();isPreview = false;
设置FOCUS_MODE_CONTINUOUS_VIDEO)之后,myParam.set("rotation",
90)失效。图片竟然不能旋转了,故这里要旋转下
Matrix matrix = new Matrix();
matrix.postRotate((float)90.0);
Bitmap rotaBitmap = Bitmap.createBitmap(mBitmap,
0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix,
false);
设置成FOCUS_MODE_CONTINUOUS_VIDEO之后,再调用Camera.autoFocus()会聚焦失败。

第六: 就是通过分析onPreviewFrame得到预览帧视频,分析亮度变化,来触Camera.autoFocus()。如果亮度变化,肯定是摄像头和被拍摄物体之间发生了相对运动,需要触发autoFocus()。某些手机里自带的
拍照软件可能就是采用这种方式。

下面提供一个我参阅处理的方案:

(使用传感器处理,手机移动则自动对焦处理,其中部分代码进行了修整)

import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.Log;

import java.util.Calendar;

/**
 * 创建时间:2017/7/24
 * 编写者:xxx
 * 功能描述:加速度控制器  用来控制对焦
 */

public class SensorControler implements SensorEventListener {
    public static final String TAG = "SensorControler";
    private SensorManager mSensorManager;
    private Sensor mSensor;

    private int mX, mY, mZ;
    private long lastStaticStamp = 0;
    Calendar mCalendar;

    boolean isFocusing = false;
    boolean canFocusIn = false;  //内部是否能够对焦控制机制
    boolean canFocus = false;

    public static final int DELEY_DURATION = 500;

    public static final int STATUS_NONE = 0;
    public static final int STATUS_STATIC = 1;
    public static final int STATUS_MOVE = 2;
    private int STATUE = STATUS_NONE;

    private CameraFocusListener mCameraFocusListener;

    private static SensorControler mInstance;

    private int foucsing = 1;  //1 表示没有被锁定 0表示被锁定

    private SensorControler() {
        mSensorManager = (SensorManager) context.getSystemService(Activity.SENSOR_SERVICE);
        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);// TYPE_GRAVITY
    }

    private static Context context;
    public static SensorControler getInstance(Context _context) {
        context = _context;
        if (mInstance == null) {
            mInstance = new SensorControler();
        }
        return mInstance;
    }

    public void setCameraFocusListener(CameraFocusListener mCameraFocusListener) {
        this.mCameraFocusListener = mCameraFocusListener;
    }

    public void onStart() {
        restParams();
        canFocus = true;
        mSensorManager.registerListener(this, mSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
    }

    public void onStop() {
        mSensorManager.unregisterListener(this, mSensor);
        canFocus = false;
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }



    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor == null) {
            return;
        }

        if (isFocusing) {
            restParams();
            return;
        }

        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            int x = (int) event.values[0];
            int y = (int) event.values[1];
            int z = (int) event.values[2];
            mCalendar = Calendar.getInstance();
            long stamp = mCalendar.getTimeInMillis();// 1393844912
            int second = mCalendar.get(Calendar.SECOND);// 53
            if (STATUE != STATUS_NONE) {
                int px = Math.abs(mX - x);
                int py = Math.abs(mY - y);
                int pz = Math.abs(mZ - z);
//                Log.d(TAG, "pX:" + px + "  pY:" + py + "  pZ:" + pz + "    stamp:"
//                        + stamp + "  second:" + second);
                double value = Math.sqrt(px * px + py * py + pz * pz);

//                Log.d("TAG", "value:"+value);
                Log.d("TAG", "canFocusIn:"+canFocusIn);
//                Log.d("TAG", "stamp - lastStaticStamp > DELEY_DURATION:"+(stamp - lastStaticStamp > DELEY_DURATION));
//                Log.d("TAG", "!isFocusing:"+!isFocusing);
                if (value > 1.4) {
//                    textviewF.setText("检测手机在移动..");
//                    Log.i(TAG,"mobile moving");
                    STATUE = STATUS_MOVE;
                } else {
//                    textviewF.setText("检测手机静止..");
//                    Log.i(TAG,"mobile static");
                    //上一次状态是move,记录静态时间点
                    if (STATUE == STATUS_MOVE) {
                        lastStaticStamp = stamp;
                        canFocusIn = true;
                    }

                    if (canFocusIn) {
                        if (stamp - lastStaticStamp > DELEY_DURATION) {
                            //移动后静止一段时间,可以发生对焦行为
                            if (!isFocusing) {
                                canFocusIn = false;
                                if (mCameraFocusListener != null) {
                                    mCameraFocusListener.onFocus();
                                }
                            }
                        }
                    }

                    STATUE = STATUS_STATIC;
                }
            } else {
                lastStaticStamp = stamp;
                STATUE = STATUS_STATIC;
            }

            mX = x;
            mY = y;
            mZ = z;
        }
    }

    private void restParams() {
        STATUE = STATUS_NONE;
        canFocusIn = false;
        mX = 0;
        mY = 0;
        mZ = 0;
    }

    /**
     * 对焦是否被锁定
     *
     * @return
     */
    public boolean isFocusLocked() {
        if(canFocus) {
            return foucsing <= 0;
        }
        return false;
    }

    /**
     * 锁定对焦
     */
    public void lockFocus() {
        isFocusing = true;
        foucsing--;
        Log.i(TAG, "lockFocus");
    }

    /**
     * 解锁对焦
     */
    public void unlockFocus() {
        isFocusing = false;
        foucsing++;
        Log.i(TAG, "unlockFocus");
    }

    public void restFoucs() {
        foucsing = 1;
    }

    public interface CameraFocusListener {
        void onFocus();
    }
}

用法:在需要传感器触发的位置,设置回调监听

//自动聚焦监听
SensorControler.getInstance(getContext()).setCameraFocusListener(new SensorControler.CameraFocusListener() {
    @Override
    public void onFocus() {
        mCameraView.onFocus(new Point(getWidth() / 2, getHeight() / 2), autoFocusCallback);
        //设置聚焦
        mFocusImageView.startFocus(new Point(getWidth() / 2, getHeight() / 2));
    }
});
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容