2014-06-05 45 views
1

我已经看到了关于这个话题的几个问题,但是没有解决那我的问题。ImageView的位图方向不正确

我动态创建ImageViews,并允许用户采取/添加项目的照片清单。下面的代码存在生成位图和填充的ImageView:

protected void addPhotosToView(ArrayList<String> uris) { 
    for (String uriString : uris) { 
     try { 
      Uri uri = Uri.parse(uriString); 
      File imageFile = new File(uri.getPath()); 
      int orientation = resolveBitmapOrientation(imageFile); 
      Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri); 
      bitmap = applyOrientation(bitmap, orientation); 

      ImageView image = new ImageView(ItemActivity.this); 

      int h = 100; // height in pixels 
      int w = 100; // width in pixels  
      Bitmap scaled = Bitmap.createScaledBitmap(bitmap, h, w, true); 

      image.setImageBitmap(scaled); 

      LinearLayout photoLayout = (LinearLayout) findViewById(R.id.itemPhotoLayout); 
      photoLayout.addView(image); 

      addClickListener(image, uri); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

但是一旦图像添加或采取一些图像显示了错误的方向。纵向存储在手机中的一些照片以纵向显示,而其他照片则呈现横向显示。风景照片同样是任意的。

这似乎并非要在

正如你可以在代码中看到,我试图让所有的设备(即我看到这对设备是三星S4)发生/应用使用方向变化EXIF标签,但我总是与该设备的定位越来越0并没有看到该请求解决问题的任何答案时,方向始终是0

我期待尽快出货这个软件,并且需要某种解决方法或解决方案,所以我愿意接受从Uris /字符串到动态水平滚动的正确图像列表的其他方式,如果这不能以其他方式解决的话。

+1

看起来像我面临的exif方向问题我通过解码位图和检查EXIF方向来解决它。如果exif数据方向存在,则位图会相应地旋转 –

+0

我相信@IllegalArgument是正确的。但是请张贴'resolveBitmapOrientation()'和'applyOrientation()'代码(仅从他们的名字来判断,似乎你已经考虑到了这一点 - 也许它们在某些情况下失败了?)。 – matiash

回答

-1

请使用此方法来显示/解码位图。它是从另一个SO帖子中拿出来的,我不记得哪个和修改后用于我的用途。这种方法如果根据在图像上存在的EXIF方向数据返回位图:

public Bitmap decodeFile(String path) {// you can provide file path here 
    int orientation; 
    try { 
     if (path == null) { 
      return null; 
     } 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     // Find the correct scale value. It should be the power of 2. 
     final int REQUIRED_SIZE = 70; 
     // final int REQUIRED_SIZE = 20; 
     int width_tmp = o.outWidth, height_tmp = o.outHeight; 
     int scale = 0; 
     while (true) { 
      if (width_tmp/2 < REQUIRED_SIZE 
        || height_tmp/2 < REQUIRED_SIZE) 
       break; 
      width_tmp /= 2; 
      height_tmp /= 2; 
      scale++; 
     } 
     // decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 
     Bitmap bm = BitmapFactory.decodeFile(path, o2); 
     Bitmap bitmap = bm; 
     ExifInterface exif = new ExifInterface(path); 
     orientation = exif 
       .getAttributeInt(ExifInterface.TAG_ORIENTATION, 1); 
     Matrix m = new Matrix(); 
     if ((orientation == ExifInterface.ORIENTATION_ROTATE_180)) { 
      m.postRotate(180); 
      bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), 
        bm.getHeight(), m, true); 
      photo(bitmap, path); 
      return bitmap; 
     } else if (orientation == ExifInterface.ORIENTATION_ROTATE_90) { 
      m.postRotate(90); 
      bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), 
        bm.getHeight(), m, true); 
      photo(bitmap, path); 
      return bitmap; 
     } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) { 
      m.postRotate(270); 
      bitmap = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), 
        bm.getHeight(), m, true); 
      photo(bitmap, path); 
      return bitmap; 
     } 
     return bitmap; 
    } catch (Exception e) { 
     return null; 
    } 

} 
+0

正如我在其他评论中说的,我在BitmapFactory.options上遇到了一些麻烦 - 任何构造它的尝试都会导致在使用时引用它的变量的NPE。有任何想法吗? – user3563124

+0

在这种情况下,一些代码和logcat的输出将是有益的,上面的代码进行测试和对我的作品所以只是给它一个尝试 –

1

你需要的位图这一切尝试this tutorial你可以下载源解码。 该应用剂量正是你想要的,也许它会帮助你,我希望,因为它适用于我的应用程序

+0

我有一些困难,得到这个正常工作。任何时候我尝试创建一个新的BitmapFactory.options实例,我都会在无精确的构造函数中得到一个NPE。 – user3563124

+1

我没有解决这个问题,所以看看这段代码,它更容易运行,只需按照它一步一步地执行即可。 http://www.c-sharpcorner.com/UploadFile/e14021/capture-image-from-camera-and-selecting-image-from-gallery-o/ – BiLL

+0

此代码还依赖于BitmapFactory.options,所以我由于NPE,无法遵循它。 我不倾向于认为它是我的任何代码,因为没有参数,而且对象完全由它自己构造。 – user3563124