如何设置相机图像方向?

4

在我的应用程序中,我添加了图像上传功能。对于所有的图像,它都很好地工作,除了相机图像。每当我从库中浏览相机图像并且肖像图像旋转90度时...以下是我的代码片段...有人可以帮助我吗?我遵循了很多教程,但它们都在kikat中运行良好...但同样的教程在ics、jellybean等中不起作用。

public class MainActivity extends Activity {
private Button browse;
private String selectedImagePath="";
private ImageView img;

private TextView messageText;

private static int SELECT_PICTURE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    img = (ImageView)findViewById(R.id.imagevw);
    browse=(Button)findViewById(R.id.browseimg);
    messageText  = (TextView)findViewById(R.id.messageText);
    browse.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
             Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent,"Select Picture"), SELECT_PICTURE);
        }
    });
}
 @Override
   public void onActivityResult(int requestCode, int resultCode, Intent data) {
       if (resultCode == RESULT_OK) {
           if (requestCode == SELECT_PICTURE) {
               Uri selectedImageUri = data.getData();

               /*String filePath = getRealPathFromURI(getActivity(), selectedImageUri );
               messageText.setText(filePath );
               Picasso.with(getActivity())
                                      .load(new File(filePath ))
                                      .centerCrop()
                                      .resize(60, 60).into( img);*/

               selectedImagePath = getPath(selectedImageUri);
               messageText.setText(selectedImagePath);
               System.out.println(requestCode);
               System.out.println("Image Path : " + selectedImagePath);
               img.setImageURI(selectedImageUri);
           }
       }
 }
 @SuppressWarnings("deprecation")
    public String getPath(Uri uri) {
       String[] projection = { MediaStore.Images.Media.DATA };
       Cursor cursor = managedQuery(uri, projection, null, null, null);
       int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
       cursor.moveToFirst();
       return cursor.getString(column_index);
   }

   }

使用 ExifInterface 来实现。 - Piyush
请查看以下链接:https://dev59.com/YmYr5IYBdhLWcg3wpbuQ 和 https://dev59.com/5Gcs5IYBdhLWcg3wlFA2。你的代码只能在某些设备上运行,而不能兼容其他大型设备。因此,请查看这些链接。 - Piyush
请点击此处查看答案:https://dev59.com/3WYq5IYBdhLWcg3w8VG8 - Shirish Herwade
5个回答

15

只需包含此代码

public void rotateImage(String file) throws IOException{

    BitmapFactory.Options bounds = new BitmapFactory.Options();
    bounds.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(file, bounds);

    BitmapFactory.Options opts = new BitmapFactory.Options();
    Bitmap bm = BitmapFactory.decodeFile(file, opts);

    int rotationAngle = getCameraPhotoOrientation(getActivity(), Uri.fromFile(file1), file1.toString());

    Matrix matrix = new Matrix();
    matrix.postRotate(rotationAngle, (float) bm.getWidth() / 2, (float) bm.getHeight() / 2);
    Bitmap rotatedBitmap = Bitmap.createBitmap(bm, 0, 0, bounds.outWidth, bounds.outHeight, matrix, true);
    FileOutputStream fos=new FileOutputStream(file);
    rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
    fos.flush();
    fos.close();
}

public static int getCameraPhotoOrientation(Context context, Uri imageUri, String imagePath){
    int rotate = 0;
    try {
        context.getContentResolver().notifyChange(imageUri, null);
        File imageFile = new File(imagePath);
        ExifInterface exif = new ExifInterface(imageFile.getAbsolutePath());
        int orientation = exif.getAttributeInt(
                ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_UNDEFINED);
        switch (orientation) {
        case ExifInterface.ORIENTATION_NORMAL:
            rotate = 0;
        case ExifInterface.ORIENTATION_ROTATE_270:
            rotate = 270;
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            rotate = 180;
            break;
        case ExifInterface.ORIENTATION_ROTATE_90:
            rotate = 90;
            break;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return rotate;
}

你的意思是我应该将这个方法添加到我的代码中? - parajs dfsb
你只需要将这段代码添加到你的程序中,并在rotateimage函数中传入图像路径。 - Sagar
file1 是传入相机意图的图片文件路径。 - Sagar

1
     String filePath = getRealPathFromURI(getActivity(), selectedImageUri );
     messageText.setText(filePath );
     Picasso.with(getActivity())
                            .load(new File(filePath ))
                            .centerCrop()
                            .resize(60, 60).into( img);

抱歉,如果它没有运行。Picasso正在处理所有这些情况,并且对我来说效果很好,这就是为什么我建议你使用这种方法。 - Nivedh
这只是一个占位符,用于在所需的图像适合图像视图之前显示图像。即使它不存在,它也可以工作。 - Nivedh
在您的onActivityResult中使用我的代码。使用ic_launcher代替rofile_image并注释掉其余代码。 - Nivedh
我做了同样的事并运行了我的应用程序,但它没有显示ic_launcher..我正在检查相机图像..与此类似的问题在这里: https://dev59.com/NW025IYBdhLWcg3wVkef - parajs dfsb
好的,那就按照那个方法来,否则我会根据你的修改。 - Nivedh
显示剩余3条评论

1

有几种方法,但我发现最简单的方法是使用Picasso库。由于这是上传情况,我们将正确获取方向,并且还可以调整图像位图大小。


将Picasso jar文件添加到项目中。 - Nivedh
为了根据您的分辨率和大小获取位图,请使用以下代码: Bitmap resizedBitmapthumb = Picasso.with(getActivity()) .load(new File(picturePath)).centerInside() .resize(size, size ).get(); - Nivedh
你仔细看过我的问题了吗?因为我已经添加了Picasso2.4.0。 - parajs dfsb

0
我用以下代码解决了图像旋转问题。
public  Bitmap rotateImageIfRequired(String imagePath) {
    int degrees = 0;

    try {
        ExifInterface exif = new ExifInterface(imagePath);
        int orientation = exif.getAttributeInt(
                ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);

        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                degrees = 90;
                break;

            case ExifInterface.ORIENTATION_ROTATE_180:
                degrees = 180;
                break;

            case ExifInterface.ORIENTATION_ROTATE_270:
                degrees = 270;
                break;
        }
    } catch (IOException e) {
        Log.e("ImageError", "Error in reading Exif data of " + imagePath, e);
    }

    BitmapFactory.Options decodeBounds = new BitmapFactory.Options();
    decodeBounds.inJustDecodeBounds = true;

    Bitmap bitmap = BitmapFactory.decodeFile(imagePath, decodeBounds);
    int numPixels = decodeBounds.outWidth * decodeBounds.outHeight;
    int maxPixels = 2048 * 1536; // requires 12 MB heap

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = (numPixels > maxPixels) ? 2 : 1;

    bitmap = BitmapFactory.decodeFile(imagePath, options);

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

    Matrix matrix = new Matrix();
    matrix.setRotate(degrees);

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

    return bitmap;
}

0

使用androidx库是一种简单的方法来完成这个任务。

**implementation 'androidx.exifinterface:exifinterface:1.3.6'**

 //inside on create
   binding.imageViewEditImage.setOnClickListener(view -> {
        Intent gallery = new Intent(Intent.ACTION_PICK, 
   MediaStore.Images.Media.INTERNAL_CONTENT_URI);
        ActivityResultLauncher.launch(gallery);
    });

//for taking picture form gallery 
 ActivityResultLauncher<Intent> ActivityResultLauncher = registerForActivityResult(  //code with exif interface
        new ActivityResultContracts.StartActivityForResult(),
        new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result) {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    Intent data = result.getData();
                    assert data != null;
                    Uri uri = data.getData();
                    try {
                        Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
                        Bitmap rotatedBitmap = rotateBitmap(bitmap, uri);
                        binding.imageViewUserImage.setImageBitmap(rotatedBitmap);

                        bitmap = Bitmap.createScaledBitmap(rotatedBitmap, 800, 800, false);
                        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
                        binding.imageViewUserImage.setTag(Utility.convert(bitmap));
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        });



//for devices who take pictures in rotated format this can fix normal image will not rotate
private Bitmap rotateBitmap(Bitmap bitmap, Uri uri) throws IOException {
    InputStream inputStream = getContentResolver().openInputStream(uri);
    ExifInterface exif = null;
    exif = new ExifInterface(inputStream);

    int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
    Matrix matrix = new Matrix();
    switch (orientation) {
        case ExifInterface.ORIENTATION_ROTATE_90:
            matrix.postRotate(90);
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            matrix.postRotate(180);
            break;
        case ExifInterface.ORIENTATION_ROTATE_270:
            matrix.postRotate(270);
            break;
        default:
            return bitmap;
    }
    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接