1. 程式人生 > >Android開發:解決三星裝置拍照後獲取的圖片被旋轉的問題

Android開發:解決三星裝置拍照後獲取的圖片被旋轉的問題

呼叫Android系統拍照功能後,三星手機拍攝後的照片被旋轉了90度,橫著拍變成豎的,豎著拍變成橫的。。。測試其它品牌的手機是正常的,就三星出現這個問題。

解決方法:

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,所以我們需要對圖片進行壓縮處理。不然在儲存圖片時會等待挺久的,螢幕會黑一會。