当我拍照时,它会逆时针旋转90度

时间:2019-08-14 09:23:39

标签: java android android-studio

我需要一种在捕获照片后自动旋转图片的方法。

它需要自动拾取旋转并进行校正。

当我拍照时,它会逆时针旋转90度。

private void CompressAndSetImage(Uri uri)
    {
        Bitmap thumbnail = null;
        try {
            thumbnail = MediaStore.Images.Media.getBitmap(getActivity().getApplicationContext().getContentResolver(), uri);
            int nh = (int) ( thumbnail.getHeight() * (1024.0 / thumbnail.getWidth()) );
            Bitmap scaled = Bitmap.createScaledBitmap(thumbnail, 1024, nh, true);
            Bitmap squareImage = cropToSquare(scaled);
            CurrImageURI =  getImageUri(getActivity().getApplicationContext(), squareImage);
            iv_child.setImageURI(CurrImageURI);
            isImageUploaded = true;

        } catch (IOException e) {
            Toast.makeText(getContext(), "Some error occured", Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }
private Bitmap cropToSquare(Bitmap bitmap){
        int width  = bitmap.getWidth();
        int height = bitmap.getHeight();
        int newWidth = (height > width) ? width : height;
        int newHeight = (height > width)? height - ( height - width) : height;
        int cropW = (width - height) / 2;
        cropW = (cropW < 0)? 0: cropW;
        int cropH = (height - width) / 2;
        cropH = (cropH < 0)? 0: cropH;
        Bitmap cropImg = Bitmap.createBitmap(bitmap, cropW, cropH, newWidth, newHeight);
        return cropImg;
    }

private Uri getImageUri(Context inContext, Bitmap inImage) {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
        return Uri.parse(path);
    }

谢谢。

2 个答案:

答案 0 :(得分:0)

如果您是出于意图打开相机,则解决旋转问题的最佳方法是在临时片段上放置旋转图标。让用户旋转图像本身并将其发布到您的最终图像视图中。

您还可以使用Android cameraX api创建自定义相机,这是Camera2 Api的包装器类,借助 setTargetRotation 您可以解决相机旋转问题。

答案 1 :(得分:0)

ExifInterface

From official doc:

  

这是用于在JPEG文件或   RAW图像文件。支持的格式有:JPEG,DNG,CR2,NEF,NRW,ARW,   RW2,ORF,PEF,SRW,RAF和HEIF。

图像旋转通常作为图像文件的一部分存储在照片的Exif数据中。您可以使用Android ExifInterface读取图像的Exif元数据 您可以使用此类来获取从默认图像库中选择的图像的正确方向。

在您的应用中应用以下代码:

首先使用当前上下文和要修复的图像URI调用以下方法。

public static Bitmap handleSamplingAndRotationBitmap(Context context, Uri selectedImage)
            throws IOException {
        int MAX_HEIGHT = 1024;
        int MAX_WIDTH = 1024;

        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        InputStream imageStream = context.getContentResolver().openInputStream(selectedImage);
        BitmapFactory.decodeStream(imageStream, null, options);
        imageStream.close();

        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, MAX_WIDTH, MAX_HEIGHT);

        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        imageStream = context.getContentResolver().openInputStream(selectedImage);
        Bitmap img = BitmapFactory.decodeStream(imageStream, null, options);

        img = rotateImageIfRequired(img, selectedImage);
        return img;
    }

CalculateInSampleSize方法:

private static int calculateInSampleSize(BitmapFactory.Options options,
                                         int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        // Calculate ratios of height and width to requested height and width
        final int heightRatio = Math.round((float) height / (float) reqHeight);
        final int widthRatio = Math.round((float) width / (float) reqWidth);

        // Choose the smallest ratio as inSampleSize value, this will guarantee a final image
        // with both dimensions larger than or equal to the requested height and width.
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;

        final float totalPixels = width * height;

        // Anything more than 2x the requested pixels we'll sample down further
        final float totalReqPixelsCap = reqWidth * reqHeight * 2;

        while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
            inSampleSize++;
        }
    }
    return inSampleSize;
}

然后是检查当前图像方向以确定旋转角度的方法:

private static Bitmap rotateImageIfRequired(Bitmap img, Uri selectedImage) throws IOException {

    ExifInterface ei = new ExifInterface(selectedImage.getPath());
    int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

    switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            return rotateImage(img, 90);
        case ExifInterface.ORIENTATION_ROTATE_180:
            return rotateImage(img, 180);
        case ExifInterface.ORIENTATION_ROTATE_270:
            return rotateImage(img, 270);
        default:
            return img;
    }
}

最后是旋转方法本身:

private static Bitmap rotateImage(Bitmap img, int degree) {
Matrix matrix = new Matrix();
matrix.postRotate(degree);
Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);
img.recycle();
return rotatedImg;
}

此代码的来源:doc