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

Android相机预览在预览中拉伸,而不是在拍照后拉伸,android,image,android-camera,Android,Image,Android Camera,我有一个应用程序,可以在肖像模式下拍照,除了预览与拍照后的图像大小不同之外,其他一切都正常工作。预览看起来失真模糊,但却充满了整个屏幕。拍照后,图像清晰,但比设备高度短或宽度小(取决于使用的设备) 下面是一些图像示例和我正在使用的一些代码 拍照前: 拍照后: 要在纵向中显示的摄影机预览代码: protected int getRotationDegrees() { android.hardware.Camera.CameraInfo info = new android.hardwa

我有一个应用程序,可以在肖像模式下拍照,除了预览与拍照后的图像大小不同之外,其他一切都正常工作。预览看起来失真模糊,但却充满了整个屏幕。拍照后,图像清晰,但比设备高度短或宽度小(取决于使用的设备)

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

拍照前:

拍照后:

要在纵向中显示的摄影机预览代码:

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;
}
private Camera.Size getoptimize(列表大小,int h,int w){
最终双纵横比公差=0.05;
双目标率=(双)w/h;
如果(大小==null){
返回null;
}
照相机。大小优化大小=空;
double minDiff=double.MAX_值;
int targetHeight=h;
用于(相机尺寸:尺寸){
双倍比率=(双倍)size.width/size.height;
如果(数学abs(比率-目标比率)>纵横比公差)继续;
if(数学绝对值(尺寸高度-目标光)
这种情况非常典型。预览帧的纵横比可能与捕获的图像不完全相同。您可能会反复查看支持的预览大小,以选择最适合您的SurfaceView的大小(我希望您这样做是正确的)。您需要通过支持的图片大小进行类似的迭代。如果无法在纵横比相同的情况下找到令人满意的一对,则需要在SurfaceView或ImageView中进行视觉“裁剪”。实现这种裁剪的最简单方法是将视图中不需要的部分与其他一些不透明视图重叠

也可以强制一个视图(SurfaceView或ImageView)挂起,部分离开屏幕。

我在另一篇解决我问题的帖子中发现了这一点


它会改变视图的大小,这样图像在总是试图填充屏幕时不会被拉伸。

您有没有将图像挂在边缘上的示例?我不认为裁剪视图对我有用,因为预览图像的纵横比看起来与拍摄的照片不同(预览中的对象看起来更短、矮胖)。我在原始帖子中添加了用于选择尺码的代码。另外,我将预览设置为FrameLayout,而不是SurfaceView或ImageView。这是否正确且有效,因为我的预览类扩展了SurfaceView?我看不到您的项目,但我猜您将从SurfaceView派生的视图添加到FrameLayout。这使得“挂起”非常容易:首先选择预览大小,然后将此视图添加到框架中,并带有负边距。ImageView也是如此。我还建议将PictureSize()设置为支持的最佳合身尺寸。太好了,谢谢。是否只是猜测和检查,然后硬编码视图上的负边距?或者我可以用我为setPreviewSize和setPictureSize选择的大小通过编程实现吗?没有猜测,您可以知道FrameLayout的大小,并且您应该知道为preview和picture选择的大小。请记住,Android会为您缩小比例,因此对于1920x1080预览,如果应用负边距后的SurfaceView为1280x720,则完全可以。