Android studio 獲取sd卡的圖片和視訊的縮圖
阿新 • • 發佈:2019-02-08
最近有個專案需要用到這個,因為獲取視訊的第一幀遇到了一個坑,所以就記錄下來。
首先先獲取圖片
/** * 根據指定的影象路徑和大小來獲取縮圖 * 此方法有兩點好處: * 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();
}
}
然後基本都記錄到這吧。