2011-09-02 76 views
46

我有这样的代码:Android获取相机位图的方位?和转回-90度

//choosed a picture 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 

    if (resultCode == RESULT_OK) { 
     if (requestCode == ImageHelper.SELECT_PICTURE) { 

      String picture   = ""; 

      Uri selectedImageUri  = data.getData(); 
      //OI FILE Manager 
      String filemanagerstring = selectedImageUri.getPath(); 
      //MEDIA GALLERY 
      String selectedImagePath = ImageHelper.getPath(mycontext, selectedImageUri); 

      picture=(selectedImagePath!=null)?selectedImagePath:filemanagerstring; 

...

这只是一个图片选择器,从画廊。这是很好的,但是当我在imageview上打开这张照片时,图像在相机上拍摄“肖像模式”时看起来不错,但是相机拍摄了“景观模式”的图像以-90度打开。

我该如何旋转这些图片?

Bitmap output  = Bitmap.createBitmap(newwidth, newheight, Config.ARGB_8888); 
    Canvas canvas  = new Canvas(output); 

我想这:

Log.e("w h", bitmap.getWidth()+" "+bitmap.getHeight()); 
if (bitmap.getWidth()<bitmap.getHeight()) canvas.rotate(-90); 

,但是这是不工作,所有的图像尺寸是:* 2560 1920像素(纵向和横向模式全)

我能做些什么旋转LANDSCAPE图片?

感谢莱斯利

回答

178

如果照片是用数字照相机或智能电话,旋转通常存储在照片的Exif数据,作为图像文件的一部分。您可以使用Android ExifInterface阅读图片的Exif元数据。

首先,创建ExifInterface

ExifInterface exif = new ExifInterface(uri.getPath()); 

接下来,找到当前旋转:

int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); 

转换EXIF旋转度:

int rotationInDegrees = exifToDegrees(rotation); 

其中

private static int exifToDegrees(int exifOrientation) {   
    if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; } 
    else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) { return 180; } 
    else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) { return 270; }    
    return 0;  
} 

然后使用图像的实际旋转作为参考点,使用Matrix旋转图像。

Matrix matrix = new Matrix(); 
if (rotation != 0f) {matrix.preRotate(rotationInDegrees);} 

创建与Bitmap.createBitmap方法采取Matrix作为参数的新旋转的图像:

Bitmap.createBitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) 

其中Matrix m拥有新的轮换:

Bitmap adjustedBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, width, height, matrix, true); 

看到这些教程有用的源代码示例:

+0

很好的答案,但你如何在矩阵中使用int“旋转”? – Cole

+0

@科尔 - 我已经编辑了我的答案,包括如何在矩阵中使用旋转变量的解释。 –

+2

谢谢你这样彻底的回答! – Cole

0

最后回答在技术上是完美的,但我努力创建一个系统来管理图片,旋转,调整大小,缓存并加载到ImageViews,我可以告诉它是一个地狱。即使完成所有操作,崩溃有时会在某些设备中导致OutOfMemory。

我的观点是不要重新发明轮子,它有一个完美的设计。 Google本身鼓励您使用Glide。它工作在一条线上,超级简单易用,尺寸和功能号码都很轻巧,它管理EXIF默认为,它使用内存就像一个魅力..它简直是黑魔法编码;)

我是不知道是否Picasso还管理EXIF,但有一个快速的介绍他们两个:

https://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en

我的建议是:不要浪费你的时间和使用它们。你可以解决你的问题在一条线:

Glide.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView); 
+0

是的,但问题是,如果你已经解码/下采样举个例子,或者使用jpeg格式进行压缩。 EXIF未保留,所以您需要将属性重置为新文件。 – ngatirauks