Android:如何获取内置相机应用程序的默认相机设置

8
我看过很多教程和信息,但我找不到任何单一的地方来介绍如何将现有相机应用程序的默认设置用于任何其他自定义相机应用程序。我注意到内置相机应用程序中图像的锐度和对焦非常好。现在我正在创建自己的应用程序,并添加了一些自定义功能,但我仍然无法使图像清晰,没有模糊...我不想使用相机的Intent技术,因为之后还要进行一些图像处理。
我已经尝试使用缩放,但奇怪的是缩放不能像内置相机应用程序中那样正常工作。
这是我的表面更改代码。
   public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
{
    Log.e(TAG, "surfaceChanged");

    // XXX stopPreview() will crash if preview is not running
    if (mPreviewRunning) {
        mCamera.stopPreview();
    }


     Camera.Parameters params = mCamera.getParameters();
     List<Camera.Size> sizes = params.getSupportedPreviewSizes();
     mFrameWidth =  w;
     mFrameHeight = h;

     // selecting optimal camera preview size
     {
         double minDiff = Double.MAX_VALUE;
         for (Camera.Size size : sizes) 
         {
             if (Math.abs(size.height - h) < minDiff) 
             {
                 mFrameWidth = size.width;
                 mFrameHeight = size.height;
                 minDiff = Math.abs(size.height - h);
             }
         }
     }

    try 
    {

        //params.set("rotation", 180);
        //params.set("orientation", "landscape");
        //params.set("auto", "WHITE_BALANCE_AUTO");//WHITE_BALANCE_AUTO 




        Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

        if(display.getRotation() == Surface.ROTATION_0)
        {
            params.setPreviewSize(mFrameHeight, mFrameWidth);                           
            mCamera.setDisplayOrientation(90);
        }

        if(display.getRotation() == Surface.ROTATION_90)
        {
            params.setPreviewSize(mFrameWidth, mFrameHeight);                           
        }

        if(display.getRotation() == Surface.ROTATION_180)
        {
            params.setPreviewSize(mFrameHeight, mFrameWidth);               
        }

        if(display.getRotation() == Surface.ROTATION_270)
        {
            params.setPreviewSize(mFrameWidth, mFrameHeight);
            mCamera.setDisplayOrientation(180);
        }

        if(params.isZoomSupported())
        {

            Log.e(TAG, params.getZoom()+"surfaceChanged camer zoom"+params.getMinExposureCompensation());
            params.setZoom(params.getMaxZoom());
            params.setExposureCompensation(1);
                  //    params.setColorEffect("none");
            params.setWhiteBalance(params.WHITE_BALANCE_AUTO);
            params.setFocusMode(params.FOCUS_MODE_AUTO);
            params.setSceneMode(params.SCENE_MODE_ACTION);

        }

        params.set("auto", "FOCUS_MODE_AUTO");

        params.setPreviewSize(mFrameWidth,mFrameHeight);
        mCamera.setParameters(params);

        mCamera.setPreviewDisplay(holder);
    }
    catch (IOException e) 
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    mCamera.startPreview();
    mPreviewRunning = true;
}  

请告诉我如何使相机预览与内置应用程序的预览完全相同。

你看过Android相机应用程序代码吗?你可以拉取它以支持你将要使用的最低版本的操作系统,并将其作为基础。请记住,每个操作系统升级都会增加功能,而你设备的制造商可能支持其他设备不存在的功能。 - Idistic
2个回答

2
你是指全屏相机预览吗?
我使用以下代码:
this.requestWindowFeature(Window.FEATURE_NO_TITLE); //no title
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //no status bar, etc

还有这个:

setContentView(R.layout.main);
    addContentView(overlay, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
((FrameLayout) findViewById(R.id.preview)).addView(preview);

第一个代码片段将应用程序设置为全屏并隐藏标题和状态栏。 第二个代码片段将我的叠加层(扩展视图)添加到主布局中。

这是我的XML和Java代码: main.xml:

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <FrameLayout
        android:id="@+id/preview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />
    </LinearLayout>

Overlay.java:

class Overlay extends View {
    String text = "";
    String textBearing = "Bearing: ";

    public Overlay(Context context) {
            super(context);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.WHITE);
        paint.setTextSize(16);
        canvas.drawText(text, 20, 20, paint);
        canvas.drawText(textBearing, 20, 50, paint);
        super.onDraw(canvas);
    }
}

我的活动:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE); //no title
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); //fullscreen
    overlay = new Overlay(this);
    setContentView(R.layout.main);
    addContentView(overlay, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
    camera = getCameraInstance(); //camera.open();
    preview = new Preview(this, camera);
    ((FrameLayout) findViewById(R.id.preview)).addView(preview);
}

希望能帮到你。

你的代码考虑到了进度条所占用的空间吗?我有类似的解决方案,但我必须获取进度条的高度并将其添加为填充。 - Johnny

0

我遇到了和你一样的问题。在阅读内置相机应用程序的源代码并比较内置相机和我的相机的对焦处理后,我意识到问题出在自动对焦上。

所以尝试这个:

    mCamera.autoFocus(new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera camera) {
            mCamera.takePicture(null, null, mPicture);
        }
    }); 

这使得结果图像与内置相机一样清晰。 文档在这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接