Android - ImageView 方向因设备而异
Posted
技术标签:
【中文标题】Android - ImageView 方向因设备而异【英文标题】:Android - ImageView Orientation changes depending on device 【发布时间】:2013-12-15 15:10:54 【问题描述】:我做了一个自定义的相机应用程序,我想在 ImageView 上显示图片。我在 3 款不同的手机(HTC Desire Z、Galaxy S4 和 Galaxy S2)上启动了我的程序。 在 HTC 上,图片的方向在 ImageView 中得到尊重,但在 Galaxys 中则没有。
我的程序是这样工作的:
-> 我用自定义相机应用拍照
->我根据手机方向(OrientationEventListener)设置图片的EXIF标志:
switch(getOrientation(rot))
case VERTICAL_ENDROIT : params.setRotation(90); break;
case HORIZONTAL_ENDROIT : params.setRotation(0); break;
case VERTICAL_ENVERS : params.setRotation(270); break;
case HORIZONTAL_ENVERS : params.setRotation(180); break;
camera.setParameters(params);
此功能在所有手机上都运行良好,它们都检测到并分配了正确的方向。
->我保存为JPG格式
-> 我将图片发送到 ImageView
Bitmap bm2 = BitmapFactory.decodeFile(photoItem.getPathPhoto(),options);
imageView.setImageBitmap(bm2);
对于 Galaxy,ImageView 上的 Orientation 总是相同的,对应 params.setRotation(0)。 HTC 没问题。
所以我试图在将图片发送到 ImageView 之前查看图片的 exif 标志:
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
奇怪的是,对于 HTC,orientation 总是为 0 值,而对于三星,orientation 得到了正确的值 (1 3 6 8)。
结论: Galaxy Phones 的 EXIF 方向值可以,但 ImageView 上的方向不好。
对于 HTC 手机,EXIF 方向值是错误的,但方向是可以的。 (wtf?)
感谢您的回答:)
PS:我不想使用矩阵或图像处理的东西,因为我的 CPU/内存资源非常低
【问题讨论】:
【参考方案1】:try
final File f = new File(directory, name);
ExifInterface ei = new ExifInterface(f.getAbsolutePath());
int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
try
switch (orientation)
case ExifInterface.ORIENTATION_ROTATE_90:
b = RotateBitmap(b, 90);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
b = RotateBitmap(b, 180);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
b = RotateBitmap(b, 270);
break;
// etc.
catch (OutOfMemoryError err)
catch (Exception e)
return b;
catch (FileNotFoundException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
public static Bitmap RotateBitmap(Bitmap source, float angle)
Matrix matrix = new Matrix();
matrix.postRotate(angle);
source = Bitmap.createBitmap(source, 0, 0, source.getWidth(),
source.getHeight(), matrix, true);
if (source != null)
b = null;
return source;
此代码将完成您需要的功能。
【讨论】:
是的,它适用于矩阵我试过了,但我遇到了很多内存问题。 :// 使用单个位图 obj 并在任何地方替换该位图。在获取位图时也使用 Bitmap.Config.ARGB_8888;位图选项,会稍微减少这个内存问题。【参考方案2】:试试下面的代码
try
File f = new File(imagePath);
ExifInterface exif = new ExifInterface(f.getPath());
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int angle = 0;
if (orientation == ExifInterface.ORIENTATION_ROTATE_90)
angle = 90;
else if (orientation == ExifInterface.ORIENTATION_ROTATE_180)
angle = 180;
else if (orientation == ExifInterface.ORIENTATION_ROTATE_270)
angle = 270;
Matrix mat = new Matrix();
mat.postRotate(angle);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bmp = BitmapFactory.decodeStream(new FileInputStream(f),
null, options);
bitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(),
bmp.getHeight(), mat, true);
ByteArrayOutputStream outstudentstreamOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100,
outstudentstreamOutputStream);
imageView.setImageBitmap(bitmap);
catch (IOException e)
Log.w("TAG", "-- Error in setting image");
catch (OutOfMemoryError oom)
Log.w("TAG", "-- OOM Error in setting image");
【讨论】:
【参考方案3】:我发现为什么 Galaxy 和 HTC 的方向不一样。 HTC 不使用 EXIF 标志来定位图片。图片以正确的方向本地保存。
【讨论】:
以上是关于Android - ImageView 方向因设备而异的主要内容,如果未能解决你的问题,请参考以下文章
在 imageview 中使用时从相机或画廊拍摄的图片其方向发生变化,有时在 Android 中会垂直拉伸
Android - imageView 上方的视图出现在某些设备上,但未出现在 Nexus 4 上