Android部分手機拍照后獲取的圖片被旋轉(zhuǎn)問題的解決方法
調(diào)用Android系統(tǒng)拍照功能后,三星手機拍攝后的照片被旋轉(zhuǎn)了90度,橫著拍給你變成豎的,豎的拍給你變成橫的。其它品牌的手機都是正常的,就三星出現(xiàn)這個怪事。
在Android適配上,我原來一直以為國內(nèi)的小米手機夠奇葩了,結(jié)果還有更奇葩的!你說你沒事旋轉(zhuǎn)照片干啥,實在是猜不透其居心何在,純粹是在給開發(fā)者制造麻煩啊!
解決辦法是獲取到拍照后照片被旋轉(zhuǎn)的角度,再旋轉(zhuǎn)回去就好了。
具體思路:
1、首先在調(diào)用拍照方法時,保存拍照后的相片原圖,得到原圖路徑,(PhotoBitmapUtils是我自己寫的一個工具類)
String fileName = ""; /** * 啟動相機拍照 */ private void addBitmapShoots() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 設(shè)置圖片要保存的 根路徑+文件名 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、在獲取相機返回的回調(diào)方法onActivityResult()中,修復(fù)被旋轉(zhuǎn)的圖片并取得修復(fù)后的圖片路徑,有了這個路徑后就可以展示出來了
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // 獲取相機拍照返回 if (resultCode == Activity.RESULT_OK && requestCode == OPEN_CAMERA) { // 得到修復(fù)后的照片路徑 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(); } } /** * 使用當(dāng)前系統(tǒng)時間作為上傳圖片的名稱 * * @return 存儲的根路徑+圖片名稱 */ public static String getPhotoFileName(Context context) { File file = new File(getPhoneRootPath(context) + FILES_NAME); // 判斷文件是否已經(jīng)存在,不存在則創(chuàng)建 if (!file.exists()) { file.mkdirs(); } // 設(shè)置圖片文件名稱 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); // 把數(shù)據(jù)寫入文件,100表示不壓縮 mbitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream); return fileName; } catch (Exception e) { e.printStackTrace(); return null; } finally { try { if (outStream != null) { // 記得要關(guān)閉流! 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; // 圖片的大小設(shè)置為原來的十分之一 Bitmap bmp = BitmapFactory.decodeFile(path, options); options = null; return bmp; } /** * 處理旋轉(zhuǎn)后的圖片 * @param originpath 原圖路徑 * @param context 上下文 * @return 返回修復(fù)完畢后的圖片路徑 */ public static String amendRotatePhoto(String originpath, Context context) { // 取得圖片旋轉(zhuǎn)角度 int angle = readPictureDegree(originpath); // 把原圖壓縮后得到Bitmap對象 Bitmap bmp = getCompressPhoto(originpath);; // 修復(fù)圖片被旋轉(zhuǎn)的角度 Bitmap bitmap = rotaingImageView(angle, bmp); // 保存修復(fù)后的圖片并返回保存后的圖片路徑 return savePhotoToSD(bitmap, context); } /** * 讀取照片旋轉(zhuǎn)角度 * * @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; } /** * 旋轉(zhuǎn)圖片 * @param angle 被旋轉(zhuǎn)角度 * @param bitmap 圖片對象 * @return 旋轉(zhuǎn)后的圖片 */ public static Bitmap rotaingImageView(int angle, Bitmap bitmap) { Bitmap returnBm = null; // 根據(jù)旋轉(zhuǎn)角度,生成旋轉(zhuǎn)矩陣 Matrix matrix = new Matrix(); matrix.postRotate(angle); try { // 將原始圖片按照旋轉(zhuǎn)矩陣進行旋轉(zhuǎn),并得到新的圖片 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; } }
在調(diào)用修復(fù)圖片角度方法的時候需要注意,現(xiàn)在的手機像素越來越大,拍完后一張照片有近10M,所以我們需要對圖片進行壓縮處理。不然在保存圖片時會等待挺久的,屏幕會黑一會。
參考文檔1
參考文檔2
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android實現(xiàn)屏幕旋轉(zhuǎn)方法總結(jié)
- Android中利用matrix 控制圖片的旋轉(zhuǎn)、縮放、移動
- Android Tween動畫之RotateAnimation實現(xiàn)圖片不停旋轉(zhuǎn)效果實例介紹
- Android開發(fā) 旋轉(zhuǎn)屏幕導(dǎo)致Activity重建解決方法
- Android實現(xiàn)圖片反轉(zhuǎn)、翻轉(zhuǎn)、旋轉(zhuǎn)、放大和縮小
- Android編程中調(diào)用Camera時預(yù)覽畫面有旋轉(zhuǎn)問題的解決方法
- Android開發(fā)之圖形圖像與動畫(二)Animation實現(xiàn)圖像的漸變/縮放/位移/旋轉(zhuǎn)
- Android 圖片縮放與旋轉(zhuǎn)的實現(xiàn)詳解
- Android編程實現(xiàn)RotateAnimation設(shè)置中心點旋轉(zhuǎn)動畫效果
- android實現(xiàn)icon動態(tài)旋轉(zhuǎn)效果
相關(guān)文章
Android中制作進度框和環(huán)形進度條的簡單實例分享
這篇文章主要介紹了Android中制作進度框和環(huán)形進度條的簡單實例分享,環(huán)形進度條帶有基本的百分比顯示,需要的朋友可以參考下2016-03-03Android入門之Fragment嵌套Fragment的用法詳解
這篇文章主要為大家詳細介紹了Android中如何實現(xiàn)Fragment嵌套Fragment的相關(guān)資料,文中的示例代碼講解詳細,具有一定的借鑒價值,需要的可以參考一下2023-02-02Android Studio升級到3.0 Terminal 中文顯示異常解決
本篇文章主要介紹了Android Studio升級到3.0 Terminal 中文顯示異常解決,非常具有實用價值,需要的朋友可以參考下2017-10-10Android內(nèi)存溢出及內(nèi)存泄漏原因進解析
這篇文章主要介紹了Android內(nèi)存溢出及內(nèi)存泄漏原因解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-08-08詳解Android studio ndk配置cmake開發(fā)native C
這篇文章主要介紹了詳解Android studio ndk配置cmake開發(fā)native C,非常具有實用價值,需要的朋友可以參考下2017-09-09