1. 程式人生 > >三星手機拍照,上傳照片或者下載導致圖片旋轉90°的解決辦法。

三星手機拍照,上傳照片或者下載導致圖片旋轉90°的解決辦法。

專案需求。
因為專案中需要對拍照之後的圖片進行上傳。
(這也是一個簡單的問題)
但是就是三星手機(三星note3),出現拍照之後照片旋轉了九十度。
然後我們上傳上去,然後通過其他手機請求url再次顯示還是旋轉過的。

說說我們解決問題的路徑。
1.
起初以為我們上傳照片的時候就是旋轉過了的,但是檢視圖片所在的位置,結果發現圖片是正的。
那麼是為什麼再次下載圖片還是旋轉的,我們就想到了
這個類ExifInterface 這個類可以獲得圖片一些資訊
1.旋轉角度
2.時間
反正就是有很多圖片的資訊啦。
參考:
ExifInterface更多資訊
這裡最重要的可能都是旋轉角度了。
我們怎麼能獲取角度了?

   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; }

以上的程式碼可以看出來,通過圖片的路徑可以獲取到。
大家可能猜到下一步幹什麼了?
既然我們可以獲取角度,那麼我們為什麼不能改角度,因為檔案中是正的,下載下來也是正的,為什麼顯示的時候出現旋轉,估計就是因為這個旋轉屬性的問題 了(我是猜想哦)
那麼我們就嘗試著更改屬性。

 ExifInterface exifInterface = new ExifInterface(path);
 exifInterface.setAttribute(exifInterface.TAG_ORIENTATION, String.valueOf(exifInterface.ORIENTATION_ROTATE_90));
            exifInterface.saveAttributes();

再次旋轉九十度試試,結果那還是什麼變化都沒有,我擦(我那個氣啊)
屬性值的確是改了,但是就是沒有旋轉。(大家可以自行嘗試一下,驗證一下)

2.
那我就只能用其他方法了(被逼的,這裡順帶說一下我們老闆讓我把圖片的大小壓縮一下,因為我們每次都需要上傳圖片,可能需要耗費很多流量,而且有非常慢,這裡我們也優化一下,一舉兩得)

這裡可以看下我前面怎麼處理圖片縮放比例的

第一個方法:
calculateInSampleSize 搜尋這個方法
這個方法就是縮放比例。
第二個方法:
因為圖片旋轉我們需要判斷角度需要用到上面的readPictureDegree方法
第三個方法:
既然知道角度了我們就要把圖片旋轉過來,那麼怎麼旋轉啦?

 /**
     * 旋轉圖片
     *
     * @param bitmap
     * @param rotate
     * @return
     */
    private static Bitmap rotateBitmap(Bitmap bitmap, int rotate) {
        if (bitmap == null)
            return null;
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        // Setting post rotate to 90
        Matrix mtx = new Matrix();
        mtx.postRotate(rotate);
        return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
    }

然後怎麼辦?
因為我們上傳一般都是根據檔案上傳的(File),
那麼我們把旋轉之後bitmap寫入到檔案中去。

  /**
     * 新增圖片到sd卡並規定壓縮比例,100預設原圖
     */
    public static File saveBitmap(Bitmap bitmap, String savePath, int quality) {
        if (bitmap == null)
            return null;
        try {
            File f = new File(savePath);
            if (f.exists()) f.delete();
            FileOutputStream fos = new FileOutputStream(f);
            f.createNewFile();
            // 把Bitmap物件解析成流
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, fos);
            Log.d("bitmap", bitmap.getRowBytes() + "");
            fos.flush();
            fos.close();
            bitmap.recycle();
            return f;
        } catch (IOException e) {
            e.printStackTrace();
            bitmap.recycle();
            return null;
        }
    }

最後我們是這麼組裝的。

 public static File getSmallBitmap(String filePath) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
         BitmapFactory.decodeFile(filePath, options);
        // Calculate inSampleSize
        options.inSampleSize = calculateInSampleSize(options, 480, 800);
        // Decode bitmap with inSampleSize set
        options.inJustDecodeBounds = false;
        Bitmap bm = BitmapFactory.decodeFile(filePath, options);
        if (bm == null) {
            return null;
        }
        int degree = readPictureDegree(filePath);
        bm = rotateBitmap(bm, degree);
        return saveBitmap(bm, filePath, 70);
    }

我們縮放規格是480X800 所以就寫的是固定的。70是我們壓縮比例。

以上都是我們解決三星圖片旋轉的問題了。
在此感謝我們的盧浩小同學的幫助。