開發相機程序之實現自動對焦和分辨率設置功能

 

 

 

今天我們來講一下在Android平臺上開發相機的問題!這裡講的是調用系統相機。

 

 

 

 

1、從xml文件中得到surfaceview對象

 

 

[html]  surfaceView = (SurfaceView) findViewById(R.id.g3_server_preview);  

 

surfaceView = (SurfaceView) findViewById(R.id.g3_server_preview);

2、之後聲明一些回調方法,用於打開相機,設置相機的參數 

 

 

[html]  // SurfaceHodler 回調,處理打開相機,關閉相機以及照片尺寸的改變  

SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {  

    @Override  

    public void surfaceCreated(SurfaceHolder holder) {  

        // 打開相機  

        camera = Camera.open();  

        try {  

            // 設置預覽  

            camera.setPreviewDisplay(holder);  

        } catch (IOException e) {  

            e.printStackTrace();  

        }  

    }  

  

    @Override  

    public void surfaceChanged(SurfaceHolder holder, int format, int width,  

            int height) {  

        // 獲得相機參數  

        Camera.Parameters parameters = camera.getParameters();  

        // SDK版本選擇,兼容  

        if (Integer.parseInt(Build.VERSION.SDK) >= 8) {  

            setDisplayOrientation(camera, 90);  

        } else {  

            if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {  

                parameters.set("orientation", "portrait");  

                parameters.set("rotation", 90);  

            }  

            if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {  

                parameters.set("orientation", "landscape");  

                parameters.set("rotation", 90);  

            }  

        }  

        // 設置預覽大小  

        parameters.setPreviewSize(width, height);  

        pic_Width = g3_setting.getInt(AppData.G3_PIC_WIDTH, 640);  

        pic_Height = g3_setting.getInt(AppData.G3_PIC_HEIGHT, 800);  

        Log.i("Travel", pic_Width + ":" + pic_Height);  

        // 設置照片大小  

        parameters.setPictureSize(pic_Width, pic_Height);  

        // 設置照片格式  

        // parameters.setPictureFormat(PixelFormat.RGB_565);  

        // 開始預覽  

        camera.startPreview();  

        // 設置相機參數  

        camera.setParameters(parameters);  

    }  

  

    @Override  

    public void surfaceDestroyed(SurfaceHolder holder) {  

        // 停止預覽  

        if (camera != null) {  

            camera.stopPreview();  

            // 釋放相機資源  

            camera.release();  

            camera = null;  

        }  

    }  

};  

 

// SurfaceHodler 回調,處理打開相機,關閉相機以及照片尺寸的改變

SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {

@Override

public void surfaceCreated(SurfaceHolder holder) {

// 打開相機

camera = Camera.open();

try {

// 設置預覽

camera.setPreviewDisplay(holder);

} catch (IOException e) {

e.printStackTrace();

}

}

 

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) {

// 獲得相機參數

Camera.Parameters parameters = camera.getParameters();

// SDK版本選擇,兼容

if (Integer.parseInt(Build.VERSION.SDK) >= 8) {

setDisplayOrientation(camera, 90);

} else {

if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {

parameters.set("orientation", "portrait");

parameters.set("rotation", 90);

}

if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {

parameters.set("orientation", "landscape");

parameters.set("rotation", 90);

}

}

// 設置預覽大小

parameters.setPreviewSize(width, height);

pic_Width = g3_setting.getInt(AppData.G3_PIC_WIDTH, 640);

pic_Height = g3_setting.getInt(AppData.G3_PIC_HEIGHT, 800);

Log.i("Travel", pic_Width + ":" + pic_Height);

// 設置照片大小

parameters.setPictureSize(pic_Width, pic_Height);

// 設置照片格式

// parameters.setPictureFormat(PixelFormat.RGB_565);

// 開始預覽

camera.startPreview();

// 設置相機參數

camera.setParameters(parameters);

}

 

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

// 停止預覽

if (camera != null) {

camera.stopPreview();

// 釋放相機資源

camera.release();

camera = null;

}

}

};[html] view plaincopyprint?protected void setDisplayOrientation(Camera camera, int angle) {  

    Method downPolymorphic;  

    try {  

        downPolymorphic = camera.getClass().getMethod(  

                "setDisplayOrientation", new Class[] { int.class });  

        if (downPolymorphic != null)  

            downPolymorphic.invoke(camera, new Object[] { angle });  

    } catch (Exception e1) {  

    }  

}  

 

protected void setDisplayOrientation(Camera camera, int angle) {

Method downPolymorphic;

try {

downPolymorphic = camera.getClass().getMethod(

"setDisplayOrientation", new Class[] { int.class });

if (downPolymorphic != null)

downPolymorphic.invoke(camera, new Object[] { angle });

} catch (Exception e1) {

}

}

 

3、然後設置surfaceview參數,加載回調方法 

 

 

[html]  // 設置屏幕常亮  

surfaceView.setKeepScreenOn(true);  

surfaceView.setFocusable(true);  

releaseCamera();  

// 從SurfaceView中獲得SurfaceHolder  

surfaceView.getHolder().addCallback(surfaceCallback);  

// 為SurfaceHolder 添加回調  

// surfaceHolder.addCallback(surfaceCallback);  

surfaceView.getHolder()  

        .setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  

 

// 設置屏幕常亮

surfaceView.setKeepScreenOn(true);

surfaceView.setFocusable(true);

releaseCamera();

// 從SurfaceView中獲得SurfaceHolder

surfaceView.getHolder().addCallback(surfaceCallback);

// 為SurfaceHolder 添加回調

// surfaceHolder.addCallback(surfaceCallback);

surfaceView.getHolder()

.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);釋放相機資源

[html]  private void releaseCamera() {  

    // TODO Auto-generated method stub  

    if (camera != null) {  

        camera.stopPreview();  

        // 釋放相機資源  

        camera.release();  

        camera = null;  

    }  

}  

 

private void releaseCamera() {

// TODO Auto-generated method stub

if (camera != null) {

camera.stopPreview();

// 釋放相機資源

camera.release();

camera = null;

}

}

4、配置相機響聲音還是震動的回調方法 

 

 

[html]  Camera.ShutterCallback shutter = new ShutterCallback() {  

  

    @Override  

    public void onShutter() {  

        // TODO Auto-generated method stub  

        if (tone == null) {  

            // 發出提示用戶的聲音  

            tone = new ToneGenerator(AudioManager.STREAM_SYSTEM,  

                    ToneGenerator.MAX_VOLUME);  

        }  

        if (g3_setting.getBoolean(AppData.G3_CONFIG_AUDIO, true)) {  

            tone.startTone(ToneGenerator.TONE_PROP_BEEP);  

        } else {  

            tone.stopTone();  

            Vibrator vibrator = (Vibrator) context  

                    .getSystemService(Service.VIBRATOR_SERVICE);  

            vibrator.vibrate(100);  

        }  

    }  

};  

 

Camera.ShutterCallback shutter = new ShutterCallback() {

 

@Override

public void onShutter() {

// TODO Auto-generated method stub

if (tone == null) {

// 發出提示用戶的聲音

tone = new ToneGenerator(AudioManager.STREAM_SYSTEM,

ToneGenerator.MAX_VOLUME);

}

if (g3_setting.getBoolean(AppData.G3_CONFIG_AUDIO, true)) {

tone.startTone(ToneGenerator.TONE_PROP_BEEP);

} else {

tone.stopTone();

Vibrator vibrator = (Vibrator) context

.getSystemService(Service.VIBRATOR_SERVICE);

vibrator.vibrate(100);

}

}

};

小插曲,判斷系統聲音能否關閉 

 

 

[html]  File file = new File("/system/media/audio/ui/Camera_click.ogg");  

if (!file.canWrite()) {  

    Tools.showToast(context, "設置聲音無效!");  

} else {  

    file.renameTo(new File("/system/media/audio/ui/Camera_click.ogg1"));  

}  

 

File file = new File("/system/media/audio/ui/Camera_click.ogg");

if (!file.canWrite()) {

Tools.showToast(context, "設置聲音無效!");

} else {

file.renameTo(new File("/system/media/audio/ui/Camera_click.ogg1"));

}

5、自動對焦並拍照 

 

 

[html]  // 對焦成功再拍照  

camera.autoFocus(new AutoFocusCallback() {  

  

    @Override  

    public void onAutoFocus(boolean success, Camera camera) {  

        // TODO Auto-generated method stub  

        // success為true表示對焦成功  

        if (success) {  

            if (camera != null) {  

                // 停止預覽  

                camera.stopPreview();  

                // 拍照  

                camera.takePicture(shutter, null, pictureCallback);  

            }  

        }  

    }  

});  

 

// 對焦成功再拍照

camera.autoFocus(new AutoFocusCallback() {

 

@Override

public void onAutoFocus(boolean success, Camera camera) {

// TODO Auto-generated method stub

// success為true表示對焦成功

if (success) {

if (camera != null) {

// 停止預覽

camera.stopPreview();

// 拍照

camera.takePicture(shutter, null, pictureCallback);

}

}

}

});

[html]  // 照片回調  

Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {  

    @Override  

    public void onPictureTaken(byte[] data, Camera camera) {  

        Log.i("G3", "picture operating………….");  

        new SavePictureTask().execute(data);  

        camera.startPreview();  

    }  

};  

 

// 照片回調

Camera.PictureCallback pictureCallback = new Camera.PictureCallback() {

@Override

public void onPictureTaken(byte[] data, Camera camera) {

Log.i("G3", "picture operating………….");

new SavePictureTask().execute(data);

camera.startPreview();

}

};

[html]  // 保存照片任務類  

class SavePictureTask extends AsyncTask<byte[], String, String> {  

    @Override  

    protected String doInBackground(byte[]… params) {  

        Log.i("G3", "picture saving………….");  

        File path = new File(Tools.getSDPath());  

        if (!path.exists()) {  

            path.mkdirs();  

        }  

        // 創建文件  

        File picture = new File(Tools.getSDPath(), Tools.initPhotoName());  

        try {  

            // 獲得文件輸出流  

            FileOutputStream fos = new FileOutputStream(picture.getPath());  

            // 寫到該文件  

            fos.write(params[0]);  

            // 關閉文件流  

            fos.close();  

        } catch (Exception e) {  

            e.printStackTrace();  

        }  

        return null;  

    }  

}  

 

// 保存照片任務類

class SavePictureTask extends AsyncTask<byte[], String, String> {

@Override

protected String doInBackground(byte[]… params) {

Log.i("G3", "picture saving………….");

File path = new File(Tools.getSDPath());

if (!path.exists()) {

path.mkdirs();

}

// 創建文件

File picture = new File(Tools.getSDPath(), Tools.initPhotoName());

try {

// 獲得文件輸出流

FileOutputStream fos = new FileOutputStream(picture.getPath());

// 寫到該文件

fos.write(params[0]);

// 關閉文件流

fos.close();

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

}

6、註意事項: 

 

a.本項目代碼已經實現對焦功能,如果你的相機不能對焦,那是手機本身不支持,與硬件有關

 

b.分辨率的設置,在第3步的surfaceChanged方法裡已經實現,數據存在SharedPreference當中

 

但是有個小問題,配置分辨率頁面必須寫在另一頁面,因為surfaceCallback事件不能被remove

 

而且camera被釋放掉,仍然無作用,但原手機自帶系統相機可以實現當頁配置,所以如果你實現

 

此功能,還請賜教!

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *