12

我在一个拍摄基本照片的相机应用程序上。当我获得最佳的最佳预览尺寸时,我遇到了问题。

事实上,使用第一个代码:

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    if (isPreviewRunning) {
        mCamera.stopPreview();
    }
    Camera.Parameters parameters = mCamera.getParameters();
    mCamera.setParameters(parameters);
    mCamera.startPreview();
    isPreviewRunning = true;
}

图片质量很好:

http://img689.imageshack.us/i/04042011172937.jpg/

但是,使用此代码:

private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
    final double ASPECT_TOLERANCE = 0.05;
    double targetRatio = (double) w / h;
    if (sizes == null) return null;

    Size optimalSize = null;
    double minDiff = Double.MAX_VALUE;

    int targetHeight = h;

    // Try to find an size match aspect ratio and size
    for (Size size : sizes) {
        double ratio = (double) size.width / size.height;
        if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
        if (Math.abs(size.height - targetHeight) < minDiff) {
            optimalSize = size;
            minDiff = Math.abs(size.height - targetHeight);
        }
    }

    // Cannot find the one match the aspect ratio, ignore the requirement
    if (optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }
    return optimalSize;
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // Now that the size is known, set up the camera parameters and begin
    // the preview.
    if (isPreviewRunning) {
        mCamera.stopPreview();
    }
    Camera.Parameters parameters = mCamera.getParameters();

    List<Size> sizes = parameters.getSupportedPreviewSizes();
    Size optimalSize = getOptimalPreviewSize(sizes, w, h);
    parameters.setPreviewSize(optimalSize.width, optimalSize.height);

    mCamera.setParameters(parameters);
    mCamera.startPreview();
    isPreviewRunning =true;
}

图片完全扭曲:

http://img97.imageshack.us/i/04042011173220.jpg/

我该如何解决这个问题?

我正在使用 HTC Desire HD。

这可能也是我的保存方法?:

PictureCallback mPictureCallbackJpeg = new PictureCallback() {      
        public void onPictureTaken(byte[] imageData, Camera camera) {
    ....

    BitmapFactory.Options options=new BitmapFactory.Options();
                            options.inSampleSize = 5; 
                            Bitmap myImage = BitmapFactory.decodeByteArray(imageData, 0,imageData.length,options);
                            FileOutputStream fOut = new FileOutputStream(path + "/"+fl);
                            BufferedOutputStream bos = new BufferedOutputStream(fOut);


    myImage.compress(CompressFormat.JPEG, 100, bos);
    bos.flush();
    bos.close();
    ....
}

谢谢

4

2 回答 2

26

我刚刚遇到了同样的问题,并想出了一个类似但重量更轻的解决方案。不过,我认为您的保存方法没有任何问题。

private Camera.Size getBestPreviewSize(int width, int height)
{
        Camera.Size result=null;    
        Camera.Parameters p = camera.getParameters();
        for (Camera.Size size : p.getSupportedPreviewSizes()) {
            if (size.width<=width && size.height<=height) {
                if (result==null) {
                    result=size;
                } else {
                    int resultArea=result.width*result.height;
                    int newArea=size.width*size.height;

                    if (newArea>resultArea) {
                        result=size;
                    }
                }
            }
        }
    return result;

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    //This line helped me set the preview Display Orientation to Portrait
            //Only works API Level 8 and higher unfortunately.

    camera.setDisplayOrientation(90);

    Camera.Parameters parameters = camera.getParameters();
    Camera.Size size = getBestPreviewSize(width, height);
    parameters.setPreviewSize(size.width, size.height);
    camera.setParameters(parameters);
    camera.startPreview();

}
于 2011-04-21T07:29:26.400 回答
5

最好的方法是获得最接近纵横比的预览尺寸:

Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {
        Camera.Size result=null;
        float dr = Float.MAX_VALUE;
        float ratio = (float)width/(float)height;

        for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
            float r = (float)size.width/(float)size.height;
            if( Math.abs(r - ratio) < dr && size.width <= width && size.height <= height ) {
                dr = Math.abs(r - ratio);
                result = size;
            }
        }

        return result;
    }

其中宽度和高度参数是您的表面尺寸。

于 2012-12-08T08:44:14.327 回答