使用相机和getOptimalPreviewSize图片失真

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

事实上,有了这第一个代码:

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();
    ....
}

谢谢


我刚刚经历了同样的问题,并提出了一个类似但重量更轻的解决方案。 尽管如此,我并未发现您的储蓄方法有任何问题。

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();

}

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

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;
    }

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

链接地址: http://www.djcxy.com/p/46503.html

上一篇: Picture distorted with Camera and getOptimalPreviewSize

下一篇: Android: Jpeg saved from camera looks corrupted