最近又被測試MM找茬了,調用Android系統拍照功能後,三星手機拍攝後的照片被旋轉了90度,橫着拍給你變成豎的,豎的拍給你變成橫的。。。其它品牌的手機都是正常的,就三星出現這個怪事。
在Android適配上,我原來一直以爲國內的小米手機夠奇葩了,結果還有更奇葩的!你說你沒事旋轉照片幹啥,實在是猜不透其居心何在,純粹是在給開發者製造麻煩啊!
解決辦法是獲取到拍照後照片被旋轉的角度,再旋轉回去就好了。
具體思路:
1、首先在調用拍照方法時,保存拍照後的相片原圖,得到原圖路徑,(PhotoBitmapUtils是我自己寫的一個工具類)
String fileName = "";
/**
* 啓動相機拍照
*/
private void addBitmapShoots() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// 設置圖片要保存的 根路徑+文件名
fileName = PhotoBitmapUtils.getPhotoFileName(getContext());
File file = new File(fileName);
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, OPEN_CAMERA);
}
2、在獲取相機返回的回調方法onActivityResult()中,修復被旋轉的圖片並取得修復後的圖片路徑,有了這個路徑後就可以展示出來了
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// 獲取相機拍照返回
if (resultCode == Activity.RESULT_OK && requestCode == OPEN_CAMERA) {
// 得到修復後的照片路徑
String filepath = PhotoBitmapUtils.amendRotatePhoto(fileName, getContext());
}
}
PhotoBitmapUtils類:
/**
* 集合一些圖片工具
*
* Created by zhuwentao on 2016-07-22.
*/
public class PhotoBitmapUtils {
/**
* 存放拍攝圖片的文件夾
*/
private static final String FILES_NAME = "/MyPhoto";
/**
* 獲取的時間格式
*/
public static final String TIME_STYLE = "yyyyMMddHHmmss";
/**
* 圖片種類
*/
public static final String IMAGE_TYPE = ".png";
// 防止實例化
private PhotoBitmapUtils() {
}
/**
* 獲取手機可存儲路徑
*
* @param context 上下文
* @return 手機可存儲路徑
*/
private static String getPhoneRootPath(Context context) {
// 是否有SD卡
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
|| !Environment.isExternalStorageRemovable()) {
// 獲取SD卡根目錄
return context.getExternalCacheDir().getPath();
} else {
// 獲取apk包下的緩存路徑
return context.getCacheDir().getPath();
}
}
/**
* 使用當前系統時間作爲上傳圖片的名稱
*
* @return 存儲的根路徑+圖片名稱
*/
public static String getPhotoFileName(Context context) {
File file = new File(getPhoneRootPath(context) + FILES_NAME);
// 判斷文件是否已經存在,不存在則創建
if (!file.exists()) {
file.mkdirs();
}
// 設置圖片文件名稱
SimpleDateFormat format = new SimpleDateFormat(TIME_STYLE, Locale.getDefault());
Date date = new Date(System.currentTimeMillis());
String time = format.format(date);
String photoName = "/" + time + IMAGE_TYPE;
return file + photoName;
}
/**
* 保存Bitmap圖片在SD卡中
* 如果沒有SD卡則存在手機中
*
* @param mbitmap 需要保存的Bitmap圖片
* @return 保存成功時返回圖片的路徑,失敗時返回null
*/
public static String savePhotoToSD(Bitmap mbitmap, Context context) {
FileOutputStream outStream = null;
String fileName = getPhotoFileName(context);
try {
outStream = new FileOutputStream(fileName);
// 把數據寫入文件,100表示不壓縮
mbitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
return fileName;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (outStream != null) {
// 記得要關閉流!
outStream.close();
}
if (mbitmap != null) {
mbitmap.recycle();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 把原圖按1/10的比例壓縮
*
* @param path 原圖的路徑
* @return 壓縮後的圖片
*/
public static Bitmap getCompressPhoto(String path) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = false;
options.inSampleSize = 10; // 圖片的大小設置爲原來的十分之一
Bitmap bmp = BitmapFactory.decodeFile(path, options);
options = null;
return bmp;
}
/**
* 處理旋轉後的圖片
* @param originpath 原圖路徑
* @param context 上下文
* @return 返回修復完畢後的圖片路徑
*/
public static String amendRotatePhoto(String originpath, Context context) {
// 取得圖片旋轉角度
int angle = readPictureDegree(originpath);
// 把原圖壓縮後得到Bitmap對象
Bitmap bmp = getCompressPhoto(originpath);;
// 修復圖片被旋轉的角度
Bitmap bitmap = rotaingImageView(angle, bmp);
// 保存修復後的圖片並返回保存後的圖片路徑
return savePhotoToSD(bitmap, context);
}
/**
* 讀取照片旋轉角度
*
* @param path 照片路徑
* @return 角度
*/
public static int readPictureDegree(String path) {
int degree = 0;
try {
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;
}
/**
* 旋轉圖片
* @param angle 被旋轉角度
* @param bitmap 圖片對象
* @return 旋轉後的圖片
*/
public static Bitmap rotaingImageView(int angle, Bitmap bitmap) {
Bitmap returnBm = null;
// 根據旋轉角度,生成旋轉矩陣
Matrix matrix = new Matrix();
matrix.postRotate(angle);
try {
// 將原始圖片按照旋轉矩陣進行旋轉,並得到新的圖片
returnBm = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
} catch (OutOfMemoryError e) {
}
if (returnBm == null) {
returnBm = bitmap;
}
if (bitmap != returnBm) {
bitmap.recycle();
}
return returnBm;
}
}
在調用修復圖片角度方法的時候需要注意,現在的手機像素越來越大,拍完後一張照片有近10M,所以我們需要對圖片進行壓縮處理。不然在保存圖片時會等待挺久的,屏幕會黑一會。