android 竖屏拍照旋转90度,三星等机型上拍照后图片被旋转90度的解决方案

本文探讨了在Android7.0+三星手机上拍照后图片横屏的问题,通过分析Exif数据和图片旋转库TakePhoto,作者揭示了三星系统级Bug并提供了修复策略,包括图片压缩和旋转优化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

考虑到Android7.0以后拍照修改了调用和返回方式,找到了一个看起来还不错的第三方库,实际可能并非如此。

-TakePhoto

在三星Note3和S6上测试,发现竖屏拍照后返回的照片是横屏的,在其它手机上又是正常的。查了资料发现三星手机很多都有这个问题,看到了歪果仁开发者对这个问题近乎骂街的回复,发现这属于三星的一个系统级Bug。竖屏拍照后得到的照片文件就是横屏的,只有应用对这些照片重新处理。

/**

* 读取图片的旋转的角度

*

* @param path 图片绝对路径

* @return 图片的旋转角度

*/

private int getBitmapDegree(String path) {

int degree = 0;

try {

// 从指定路径下读取图片,并获取其EXIF信息

ExifInterface exifInterface = new ExifInterface(path);

// 获取图片的旋转信息

int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,

ExifInterface.ORIENTATION_NORMAL);

switch (orientation) {

case ExifInterface.ORIENTATION_ROTATE_90:

degree = 90;

break;

case ExifInterface.ORIENTATION_ROTATE_180:

degree = 180;

break;

case ExifInterface.ORIENTATION_ROTATE_270:

degree = 270;

break;

}

} catch (IOException e) {

e.printStackTrace();

}

return degree;

}

如上代码可以获取图片文件的旋转角度,可以发现在这些三星手机上的到的返回值都是ExifInterface.ORIENTATION_ROTATE_90,也就是说这些三星手机即便是竖屏拍照,的到的图片文件被顺时针旋转90度后,就变成了横屏文件。

还好查了一下库本身支持设置重新调整角度的配置,在

TakePhotoOptions

/**

* 是对拍的照片进行旋转角度纠正

*/

private boolean correctImage;

public void setCorrectImage(boolean correctImage) {

this.correctImage = correctImage;

}

但是设置后发现问题依然存在,不再通过gradle引入远程代码的方式,下载了TakePhoto的源码,重新以Library module的方式引入到项目中。

调试代码定位到了问题所在

ImageRotateUtil

/**

* 将图片按照某个角度进行旋转

*

* @param bm 需要旋转的图片

* @param degree 旋转角度

* @return 旋转后的图片

*/

private Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {

Bitmap returnBm = null;

// 根据旋转角度,生成旋转矩阵

Matrix matrix = new Matrix();

matrix.postRotate(degree);

try {

// 将原始图片按照旋转矩阵进行旋转,并得到新的图片

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

} catch (OutOfMemoryError e) {

e.printStackTrace();

} catch (Exception e) {

e.printStackTrace();

}

if (returnBm == null) {

returnBm = bm;

}

if (bm != returnBm) {

bm.recycle();

}

return returnBm;

}

在如上代码中returnBm重新赋值的时候,也就是将原始图片重新旋转角度得到正确角度的图片这里,这个地方尼玛OOM了。由于库没有做压缩,一张图片在重新做旋转的时候竟然需要60M的内存空间,GGG。

好吧,问题找到了,那就先改来能用吧,

/**

* 纠正照片的旋转角度

* @param path

*/

public void correctImage(Context context,Uri path){

String imagePath=TUriParse.parseOwnUri(context,path);

int degree;

if((degree=getBitmapDegree(imagePath))!=0){

// *** add to fix oom

BitmapFactory.Options opts = new BitmapFactory.Options();

opts.inJustDecodeBounds = true; // 设置成了true,不占用内存,只获取bitmap宽高

BitmapFactory.decodeFile(imagePath, opts);

opts.inSampleSize = calculateInSampleSize(opts, 360, 640); // 调用上面定义的方法计算inSampleSize值

opts.inJustDecodeBounds = false;// 使用获取到的inSampleSize值再次解析图片

opts.inPreferredConfig = Bitmap.Config.RGB_565;

opts.inDither = true;

Bitmap bitmap = BitmapFactory.decodeFile(imagePath, opts);

// *** add to fix end

if(bitmap==null)return;

Bitmap resultBitmap=rotateBitmapByDegree(bitmap,degree);

if(resultBitmap==null)return;

try {

resultBitmap.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(new File(imagePath)));

} catch (FileNotFoundException e) {

e.printStackTrace();

}catch (OutOfMemoryError e){

e.printStackTrace();

}

}

}

总的来说就是先压缩图片,编码格式改为Bitmap.Config.RGB_565,减少图片编码大小;设置opts.inSampleSize来压缩图片大小,尽量按照你需要的图片大小来压缩图片,减少OOM发生的可能性。

验证完美。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值