編輯:關於Android編程
調用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,所以我們需要對圖片進行壓縮處理。不然在保存圖片時會等待挺久的,屏幕會黑一會。
參考文檔1
參考文檔2
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。
除非我們特別為某個操作指定特定的線程,否則大部分在前台UI界面上的操作任務都執行在一個叫做UI Thread的特殊線程中。這可能存在某些隱患,因為部分在UI界面上的耗時操
相信大家對AsyncTask機制都不陌生?基本的使用的方法和注意事項都清楚,編寫一個類,繼承AsyncTask類,必須重寫doInBackground()方法,運行在子線
有些在使用越獄工具的朋友反映,使用過程中會提示“沒有找到蘋果設備”,由於這個錯誤提醒導致越獄不能繼續進行。當遇到這種情況我們應該怎麼
加入到你的項目中去在 Module 下的 build.gradle 中,加上下面這句:compile 'com.github.youngkaaa:navigati