【问题标题】:Low quality picture and what's the usage of overriding surfaceChanged when using Android Camera API低质量图片以及使用Android Camera API时覆盖surfaceChanged的用途是什么
【发布时间】:2015-07-31 04:58:42
【问题描述】:

我的应用程序有问题,具体来说,当我想(从 android Camera API)拍照并将其发送到我的服务器时,我得到了一些奇怪的图片,如下例所示:

其中包含许多噪声点,实际上尺寸/分辨率非常小(176*144 像素)。这是我对 surfaceChanged 的​​原始代码:

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // start preview with new settings
    try {
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.set("orientation", "portrait");
        mCamera.setDisplayOrientation(90);
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();
    } catch (Exception e){
        Log.e(LOG_TAG, "Error starting camera preview: " + e.getMessage());
    }
    mCamera.startPreview();
}

我试着问了一些同学这个问题,他们不知道,但其中一个给出了以下代码:

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
    try {
        // camera.stopPreview();
        // Camera.Parameters mParameters = camera.getParameters();
        Camera.Parameters parameters = mCamera.getParameters();
        Camera.Size optiSize = getBestPreviewSize(720, 720);
        if (optiSize != null) {
            parameters.setPreviewSize(optiSize.width, optiSize.height);
            parameters.setPictureSize(optiSize.width, optiSize.height);
        }
        parameters.set("orientation", "portrait");
        mCamera.setDisplayOrientation(90);
        List<String> focusModes = parameters.getSupportedFocusModes();

        if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        }
        mCamera.setParameters(parameters);
        // mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        // camera.setParameters(mParameters); // apply the changes
    } catch (Exception e) {
        // older phone - doesn't support these calls
    }
    mCamera.startPreview();
}


private Camera.Size getBestPreviewSize(int width, int height) {
    List<Camera.Size> sizes = mCamera.getParameters()
            .getSupportedPreviewSizes();
    if (sizes == null)
        return null;
    Camera.Size optimalSize = null;
    int tmpSize;

    int minWidthDiff = 1000;
    for (Camera.Size size : sizes) {
        if (size.width > size.height)
            tmpSize = size.height;
        else
            tmpSize = size.width;
        if (Math.abs(tmpSize - width) < minWidthDiff) {
            minWidthDiff = Math.abs(tmpSize - width);
            optimalSize = size;
        }
    }
    return optimalSize;
}

而且这个效果很好,它可以存储全分辨率的原始图片。尽管我修改了一些其他代码以使新代码与我的系统兼容(例如,添加 AutoFocus)。但我认为问题的出现是因为方法 surfaceChanged 因为如果我只使用自动对焦拍摄图像,它仍然不起作用。

因此我的问题是:为什么这种方法会影响我的图像质量。我认为这个方法只有在我们“改变”表面时才会被调用,比如旋转屏幕。但显然它的作用不止于此?

有人可以帮我吗?或者一些帖子来解释这个事实?非常感谢您。

【问题讨论】:

    标签: android image android-camera


    【解决方案1】:

    当表面改变时调用此方法,例如它已调整大小。调整相机的一些参数以更好地适应新配置是很常见的(例如设置适当的预览大小)。

    您在第一个代码中所做的是获取相机的Camera.Parameters,设置一个键值对(顺便说一下,the documentation 没有提到任何带有键 "orientation" 的参数 - 它可能没有任何意义)。您忘记做的是使用Camera.setParameters() 将新参数应用于相机。话又说回来,如果不实际设置任何有效参数,这将无效。

    这会导致图片质量低下的问题。您应该使用Camera.Parameters 对象来设置所需的预览和图片大小。在第二个代码块中,这是在getBestPreviewSize() 内完成的。获得可用预览尺寸的列表,并根据预览的尺寸选择最合适的尺寸。设置一个令人满意的图片大小也可能会有所帮助。

    问题是,不同的设备具有不同的参数支持值集。如果您想提供一致的功能,您应该使用Camera.Parameters.getSupported* 方法检查支持的值并进行相应的设置。

    【讨论】:

    • 非常感谢。这对我很有帮助。
    猜你喜欢
    • 1970-01-01
    • 2011-12-21
    • 1970-01-01
    • 2019-10-06
    • 1970-01-01
    • 2016-12-05
    • 2017-06-07
    • 2012-09-17
    相关资源
    最近更新 更多