Android相机预览在预览中拉伸,而不是在拍摄后拍摄

时间:2015-11-18 17:51:00

标签: android image android-camera

我有一个应用程序,以纵向模式拍照,一切正常,但预览的大小与拍摄照片后的图像大小不同。预览似乎扭曲和模糊,但填充整个屏幕。拍摄照片后,图像清晰但短于设备高度或宽度较小(取决于使用的设备)。

下面是一些图片示例和我正在使用的一些代码。

拍照前: pic1

拍摄照片后: pic2

要在肖像中显示的相机预览代码:

protected int getRotationDegrees() {
    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
    android.hardware.Camera.getCameraInfo(0, info);
    int rotation = ((WindowManager) mContext
            .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
            .getRotation();
    int degrees = 0;

    switch (rotation) {
        case Surface.ROTATION_0:
            degrees = 0;
            break;
        case Surface.ROTATION_90:
            degrees = 90;
            break;
        case Surface.ROTATION_180:
            degrees = 180;
            break;
        case Surface.ROTATION_270:
            degrees = 270;
            break;
    }

    int result = (info.orientation - degrees + 360) % 360;
    return result;
}

拍摄照片后旋转图像的代码:

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

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        Bitmap pictureBitmap = null;

        pictureBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

        int rotationDegrees = mCameraPreview.getRotationDegrees();
        //mRotation = setCameraDisplayOrientation(MainActivity.this, Camera.CameraInfo.CAMERA_FACING_BACK, mCamera);
        Matrix matrix = new Matrix();
        matrix.postRotate(rotationDegrees);

        //Bitmap scaledBitmap = Bitmap.createScaledBitmap(pictureBitmap ,previewWidth ,previewHeight ,true);
        //Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap , 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
        Bitmap rotatedBitmap = Bitmap.createBitmap(pictureBitmap , 0, 0, pictureBitmap.getWidth(), pictureBitmap.getHeight(), matrix, true);

        //rotatedBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        ImageView previewImage = (ImageView) findViewById(R.id.preview_image);
        previewImage.setImageBitmap(rotatedBitmap);
        mCameraPreview.setVisibility(View.INVISIBLE);
        mButtonCapture.setVisibility(View.INVISIBLE);
        //flCameraPreview.setVisibility(View.INVISIBLE);
    }
};

之前有没有人遇到过这个问题?我还在尝试了解相机API。提前谢谢!

编辑:我用来选择预览和图片尺寸的代码。

private Camera.Size getOptimalSize(List<Camera.Size> sizes, int h, int w) {
    final double ASPECT_TOLERANCE = 0.05;
    double targetRatio = (double) w/h;

    if (sizes == null) {
        return null;
    }

    Camera.Size optimalSize = null;

     double minDiff = Double.MAX_VALUE;

    int targetHeight = h;

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

    if (optimalSize == null) {
        minDiff = Double.MAX_VALUE;
        for (Camera.Size size : sizes) {
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }
    }

    return optimalSize;
}

2 个答案:

答案 0 :(得分:2)

我在另一篇文章中找到了comment来解决我的问题!

它会改变视图的大小,以便在始终尝试填充屏幕时不会拉伸图像。

答案 1 :(得分:0)

这种情况非常典型。预览帧的宽高比可能与捕获的图像不完全相同。您可能会迭代支持的预览大小,以选择最适合您的SurfaceView(我希望您正确执行此操作)。您需要通过支持的图片大小进行类似的迭代。如果你找不到一个宽高比相同的令人满意的一对,你需要&#34; crop&#34;可视化SurfaceView或ImageView。实现此类裁剪的最简单方法是使用其他非透明视图覆盖视图中不需要的部分。

也可以强制视图(SurfaceView或ImageView)挂出&#34;部分退出屏幕。