1. 程式人生 > >Android studio 獲取sd卡的圖片和視訊的縮圖

Android studio 獲取sd卡的圖片和視訊的縮圖

最近有個專案需要用到這個,因為獲取視訊的第一幀遇到了一個坑,所以就記錄下來。

首先先獲取圖片

/**
     * 根據指定的影象路徑和大小來獲取縮圖
     * 此方法有兩點好處:
     * 1. 使用較小的記憶體空間,第一次獲取的bitmap實際上為null,只是為了讀取寬度和高度,
     * 第二次讀取的bitmap是根據比例壓縮過的影象,第三次讀取的bitmap是所要的縮圖。
     * 2. 縮圖對於原影象來講沒有拉伸,這裡使用了2.2版本的新工具ThumbnailUtils,使
     * 用這個工具生成的影象不會被拉伸。
     *
     * @param imagePath 影象的路徑
     * @param width     指定輸出影象的寬度
     * @param height    指定輸出影象的高度
     * @return 生成的縮圖
     */
    public static Bitmap getImageThumbnail(String imagePath, int width, int height) {
        Bitmap bitmap = null;
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        // 獲取這個圖片的寬和高,注意此處的bitmap為null
        bitmap = BitmapFactory.decodeFile(imagePath, options);
        options.inJustDecodeBounds = false; // 設為 false
        // 計算縮放比
        int h = options.outHeight;
        int w = options.outWidth;
        int beWidth = w / width;
        int beHeight = h / height;
        int be = 1;
        if (beWidth < beHeight) {
            be = beWidth;
        } else {
            be = beHeight;
        }
        if (be <= 0) {
            be = 1;
        }
        options.inSampleSize = be;
        // 重新讀入圖片,讀取縮放後的bitmap,注意這次要把options.inJustDecodeBounds 設為 false
        bitmap = BitmapFactory.decodeFile(imagePath, options);
        // 利用ThumbnailUtils來建立縮圖,這裡要指定要縮放哪個Bitmap物件
        bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
                ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        return bitmap;
    }

第二種,因為傳到平臺去有角度傾斜就本地做了個處理。處理主要是獲取旋轉角度,旋轉圖片

    /**
     * 獲取縮圖
     *
     * @param pathName sd卡圖片路徑
     * @param reqWidth 圖片大小
     * @param reqHeight 圖片大小
     * @return
     */
    public static Bitmap decodeSampledBitmapFromFd(String pathName,
                                                   int reqWidth, int reqHeight) {
        int dragee = getExifOrientation(pathName);
        Log.e("TAG", "=============" + dragee);
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(pathName, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        Bitmap src = BitmapFactory.decodeFile(pathName, options);
        Bitmap bitmap = rotateBitmapByDegree(src, dragee);
        return createScaleBitmap(bitmap, reqWidth, reqHeight);
    }
//獲取旋轉 
 /**
     * 獲取旋轉角度
     *
     * @param filepath
     * @return
     */
    public static int getExifOrientation(String filepath) {
        int degree = 0;
        ExifInterface exif = null;
        try {
            exif = new ExifInterface(filepath);
        } catch (IOException ex) {
            Loglg.d("TAG", "cannot read exif" + ex);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (exif != null) {
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
            if (orientation != -1) {
                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;
                }
            }
        }
        return degree;
    }
//旋轉圖片
 /**
     * 將圖片按照某個角度進行旋轉
     *
     * @param bm     需要旋轉的圖片
     * @param degree 旋轉角度
     * @return 旋轉後的圖片
     */
    public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) {
        Bitmap returnBm = null;

        // 根據旋轉角度,生成旋轉矩陣
        Matrix matrix = new Matrix();
        matrix.postRotate(degree);
        try {
            // 將原始圖片按照旋轉矩陣進行旋轉,並得到新的圖片
            returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
        } catch (OutOfMemoryError e) {
        }
        if (returnBm == null) {
            returnBm = bm;
        }
        if (bm != returnBm) {
            bm.recycle();
        }
        return returnBm;
    }
//Bitmap處理
  private static int calculateInSampleSize(BitmapFactory.Options options,
                                             int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

    // 如果是放大圖片,filter決定是否平滑,如果是縮小圖片,filter無影響
    private static Bitmap createScaleBitmap(Bitmap src, int dstWidth,
                                            int dstHeight) {
        Bitmap dst = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false);
        if (src != dst) { // 如果沒有縮放,那麼不回收
            src.recycle(); // 釋放Bitmap的native畫素陣列
        }
        return dst;
    }


//獲取視訊的縮圖
  /**
     * 獲取視訊的縮圖
     * 先通過ThumbnailUtils來建立一個視訊的縮圖,然後再利用ThumbnailUtils來生成指定大小的縮圖。
     * 如果想要的縮圖的寬和高都小於MICRO_KIND,則型別要使用MICRO_KIND作為kind的值,這樣會節省記憶體。
     *
     * @param videoPath 視訊的路徑
     * @param width     指定輸出視訊縮圖的寬度
     * @param height    指定輸出視訊縮圖的高度度
     * @param kind      參照MediaStore.Images.Thumbnails類中的常量MINI_KIND和MICRO_KIND。
     *                  其中,MINI_KIND: 512 x 384,MICRO_KIND: 96 x 96
     * @return 指定大小的視訊縮圖
     */
    public static Bitmap getVideoThumbnail(String videoPath, int width, int height,
                                           int kind) {
        Bitmap bitmap = null;
        // 獲取視訊的縮圖
        bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);
        bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
                ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        return bitmap;
    }
或者是獲取其第一幀
    /**
     * 獲取第一幀
     *
     * @param path
     */
    public static Bitmap getThumb(String path) {
        MediaMetadataRetriever media = new MediaMetadataRetriever();
        media.setDataSource(path);
        Bitmap bitmap = media.getFrameAtTime();
		return bitmap;
    }

//獲取音訊、視訊時長
 /**
     * 獲取時長,單位是毫秒
     *
     * @param path
     * @return
     */
    public static long getDuration(String path) {
        long duration = 0L;
        MediaMetadataRetriever retr = new MediaMetadataRetriever();
        try {
            retr.setDataSource(path);
            String time = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);

            if (!TextUtils.isEmpty(time)) {
                try {
                    duration = Long.parseLong(time);
                } catch (NumberFormatException e) {
                    duration = 0L;
                }
            }
            Log.e("Tag", "=====duration====" + duration);
        } catch (IllegalArgumentException e) {
            duration = 0L;
        }

        return duration;
    }

//因為本地需要把bitmap儲存到本地,

 /**
     * 儲存縮bitmap,這個方法是可以簡化。
     *
     * @param mBitmap
     */
    public static void saveMyBitmap(Bitmap mBitmap, Context context, String thumpFileName, String thumpPath) {
        String urlpath = context.getExternalFilesDir(thumpFileName).getAbsoluteFile() + File.separator + thumpPath;
        //CommonUtil.deleteFile(new File(urlpath));//每次儲存前需要刪除這個檔案
        if (mBitmap != null) {
            try {
                File f = new File(urlpath);
                f.createNewFile();
                FileOutputStream fOut = null;
                fOut = new FileOutputStream(f);
                mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
                fOut.flush();
                fOut.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 刪除檔案
     */
    public static void deleteFile(File file) {
        if (file.exists()) { // 判斷檔案是否存在
            if (file.isFile()) { // 判斷是否是檔案
                file.delete(); // delete()方法 你應該知道 是刪除的意思;
            } else if (file.isDirectory()) { // 否則如果它是一個目錄
                File files[] = file.listFiles(); // 宣告目錄下所有的檔案 files[];
                for (int i = 0; i < files.length; i++) { // 遍歷目錄下所有的檔案
                    CommonUtil.deleteFile(files[i]); // 把每個檔案 用這個方法進行迭代,這個CommUtil是這個deleteFile的,迴圈迭代刪除
                }
            }
            file.delete();
        }
    }
然後基本都記錄到這吧。