当前位置: 首页 > 知识库问答 >
问题:

Android从画廊获取图像来旋转

平元明
2023-03-14

我试图让用户从图库中选择个人资料图片。我的问题是有些图片向右旋转。

我启动图像选择器,如下所示:

Intent photoPickerIntent = new Intent();
photoPickerIntent.setType("image/*");
photoPickerIntent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(photoPickerIntent, "Select profile picture"), Global.CODE_SELECT_PICTURE);

我得到的图像从onActivityResult这样:

Uri selectedPicture = data.getData();
profilePic = MediaStore.Images.Media.getBitmap(activity.getContentResolver(), selectedPicture);

如何使图像不旋转?

更新:

根据我收到的一些有用的答案,我设法提出了以下可行的解决方案(它只是一个可行的代码,写得不好)。我很想得到你对我如何改进的反馈!

public void onActivityResult(int requestCode, int resultCode, Intent data) {

    if (resultCode == Activity.RESULT_OK && requestCode == Global.CODE_SELECT_PICTURE) {

        // Get selected gallery image
        Uri selectedPicture = data.getData();
        // Get and resize profile image
        String[] filePathColumn = {MediaStore.Images.Media.DATA};
        Cursor cursor = activity.getContentResolver().query(selectedPicture, filePathColumn, null, null, null);
        cursor.moveToFirst();

        int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        String picturePath = cursor.getString(columnIndex);
        cursor.close();

        Bitmap loadedBitmap = BitmapFactory.decodeFile(picturePath);

        ExifInterface exif = null;
        try {
            File pictureFile = new File(picturePath);
            exif = new ExifInterface(pictureFile.getAbsolutePath());
        } catch (IOException e) {
            e.printStackTrace();
        }

        int orientation = ExifInterface.ORIENTATION_NORMAL;

        if (exif != null)
            orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                loadedBitmap = rotateBitmap(loadedBitmap, 90);
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                loadedBitmap = rotateBitmap(loadedBitmap, 180);
                break;

            case ExifInterface.ORIENTATION_ROTATE_270:
                loadedBitmap = rotateBitmap(loadedBitmap, 270);
                break;
        }           
    }
}

public static Bitmap rotateBitmap(Bitmap bitmap, int degrees) {
    Matrix matrix = new Matrix();
    matrix.postRotate(degrees);
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}

共有3个答案

乜清野
2023-03-14

我使用这些静态方法。第一个用于确定方向,第二个用于旋转图像,并根据需要缩小图像。

public static int getOrientation(Context context, Uri photoUri) {

    Cursor cursor = context.getContentResolver().query(photoUri,
            new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null);

    if (cursor == null || cursor.getCount() != 1) {
        return 90;  //Assuming it was taken portrait
    }

    cursor.moveToFirst();
    return cursor.getInt(0);
}

/**
* Rotates and shrinks as needed
*/
public static Bitmap getCorrectlyOrientedImage(Context context, Uri photoUri, int maxWidth)
                throws IOException {

            InputStream is = context.getContentResolver().openInputStream(photoUri);
            BitmapFactory.Options dbo = new BitmapFactory.Options();
            dbo.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(is, null, dbo);
            is.close();


            int rotatedWidth, rotatedHeight;
            int orientation = getOrientation(context, photoUri);

            if (orientation == 90 || orientation == 270) {
                Log.d("ImageUtil", "Will be rotated");
                rotatedWidth = dbo.outHeight;
                rotatedHeight = dbo.outWidth;
            } else {
                rotatedWidth = dbo.outWidth;
                rotatedHeight = dbo.outHeight;
            }

            Bitmap srcBitmap;
            is = context.getContentResolver().openInputStream(photoUri);
            Log.d("ImageUtil", String.format("rotatedWidth=%s, rotatedHeight=%s, maxWidth=%s",
                    rotatedWidth, rotatedHeight, maxWidth));
            if (rotatedWidth > maxWidth || rotatedHeight > maxWidth) {
                float widthRatio = ((float) rotatedWidth) / ((float) maxWidth);
                float heightRatio = ((float) rotatedHeight) / ((float) maxWidth);
                float maxRatio = Math.max(widthRatio, heightRatio);
                Log.d("ImageUtil", String.format("Shrinking. maxRatio=%s",
                        maxRatio));

                // Create the bitmap from file
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = (int) maxRatio;
                srcBitmap = BitmapFactory.decodeStream(is, null, options);
            } else {
                Log.d("ImageUtil", String.format("No need for Shrinking. maxRatio=%s",
                        1));

                srcBitmap = BitmapFactory.decodeStream(is);
                Log.d("ImageUtil", String.format("Decoded bitmap successful"));
            }
            is.close();

        /*
         * if the orientation is not 0 (or -1, which means we don't know), we
         * have to do a rotation.
         */
            if (orientation > 0) {
                Matrix matrix = new Matrix();
                matrix.postRotate(orientation);

                srcBitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(),
                        srcBitmap.getHeight(), matrix, true);
            }

            return srcBitmap;
        }
韦德厚
2023-03-14

2使用毕加索和滑翔库的单行解决方案

在花了很多时间研究图像旋转问题的很多解决方案之后,我终于找到了两个简单的解决方案。我们不需要做任何额外的工作。

使用毕加索图书馆https://github.com/square/picasso

Picasso.with(context).load("http url or sdcard url").into(imageView);

使用滑翔库https://github.com/bumptech/glide

Glide.with(this).load("http url or sdcard url").into(imgageView);

Picasso和Glide是用于处理应用程序中包含的图像的非常强大的库。它将读取图像EXIF数据并自动旋转图像。

洪德寿
2023-03-14

您可以使用ExifInterface修改方向:

public static Bitmap modifyOrientation(Bitmap bitmap, String image_absolute_path) throws IOException {
    ExifInterface ei = new ExifInterface(image_absolute_path);
    int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

    switch (orientation) {
    case ExifInterface.ORIENTATION_ROTATE_90:
        return rotate(bitmap, 90);

    case ExifInterface.ORIENTATION_ROTATE_180:
        return rotate(bitmap, 180);

    case ExifInterface.ORIENTATION_ROTATE_270:
        return rotate(bitmap, 270);

    case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
        return flip(bitmap, true, false);

    case ExifInterface.ORIENTATION_FLIP_VERTICAL:
        return flip(bitmap, false, true);

    default:
        return bitmap;
    }
}

public static Bitmap rotate(Bitmap bitmap, float degrees) {
    Matrix matrix = new Matrix();
    matrix.postRotate(degrees);
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}

public static Bitmap flip(Bitmap bitmap, boolean horizontal, boolean vertical) {
    Matrix matrix = new Matrix();
    matrix.preScale(horizontal ? -1 : 1, vertical ? -1 : 1);
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}

为了从图像的uri中获取图像的绝对路径,请检查此答案

 类似资料:
  • 嘿,谢谢你抽出时间。在我的页面中,我的应用程序的webview中加载的是照片上传: 它上传一张照片,如果你通常图片你的画廊等... 如果我点击这个输入,我可以选择一张图片,然后网站检测到更改(js:onchange)。我已经尝试了一些东西,但在我选择它之后它不会上传图片。下面是我对imgupload的编码: 我希望你能帮忙,祝你今天过得愉快

  • 此应用程序中的WebView会打开一个带有上载按钮的页面。 下面是一个代码块,可以打开一个对话框从gallery或camera上传图像。 在我的活动中,我有: 在onCreate中,我有以下内容: 文件浏览器和图库正在按预期工作。问题是,当我用相机拍照时,它没有上载到“选择文件”选项中,该选项显示状态“未选择文件”。 选择相机时: 使用相机拍摄快照:出现返回和检查选项。 关于选择检查标记: 文件未

  • > 我有一个齿轮图像,我想围绕一个固定点连续旋转。 早些时候,我通过将图像作为ImageView包含在Android类中并对其应用RotateAnimation来实现这一点。 基本上,我将ImageView注入到类中并应用旋转动画。 但是,我再也不能奢侈地使用ImageView了。我必须使用位图并在画布上旋转它。 如何使用位图在画布上连续围绕一个固定点旋转来完成前面在onDraw()方法中所做的工

  • 我正在写一个小烧瓶应用程序来识别手写数字(0-9)。我写了几乎所有的元素(机器学习模型、web应用等),但我在捕捉图像(使用画布绘制)时遇到了问题,比如: 我想获取图像并将其保存到临时文件中。我懂Python,但从未使用过JavaScript,这是使用Canvas所必需的。 HTML: JS: 函数使用浏览器保存管理器保存图像,但我想将其保存到临时文件,稍后再使用图像。

  • 我同时使用了Gallery和ViewPager小工具,我从web服务中获取图像,但我不能将它们放在ViewPager中,但在Gallery中很容易。我用这个教程是为了view pager http://mobile . tuts plus . com/tutorials/Android/Android-user-interface-design-horizontal-view-paging/ 我想

  • 我有4个Different imageview,并尝试单击所有以上传不同的图像,如许可证、Rc、配置文件等。我希望从画廊或相机对话框上传图像。类似于此布局。类似于超级布局示例