uniapp_04_獲取縮略圖的幾種方法
關(guān)于 uniapp 獲取縮略圖
- 前言
- 獲取圖片縮略圖
- 獲取視頻縮略圖
- 參考文檔
前言
項(xiàng)目中實(shí)現(xiàn)的一個(gè)文件管理功能,視頻原本是列表的方式展示, 后來(lái)就在想是否可以讓視頻向圖片一樣排列顯示一個(gè)縮略圖而不是名稱列表。
Android中,視頻和圖片都是有縮略圖的我們可以直接獲取
獲取圖片縮略圖
獲取圖片的縮略圖,我想到的方式有兩種,
第二種方式與下面視頻縮略圖獲取基本相同所以在此不做過(guò)多描述
- 壓縮圖片
利用BitmapFactory中的decodeFile對(duì)圖片進(jìn)行壓縮
- 從媒體數(shù)據(jù)庫(kù)查詢
android.provider.MediaStore.Images.Thumbnails
獲取視頻縮略圖
-
ThumbnailUtils
ThumbnailUtils 是安卓2.2添加的方法, 三個(gè)靜態(tài)方法
createVideoThumbnail(path, kind) 創(chuàng)建視頻縮略圖
extractThumbnail(bitmap, width, height) 將bitmap裁剪為指定的大小
extractThumbnail(bitmap, width, height, options) 將bitmap裁剪為指定的大小
注:
path 是文件路徑
options: ThumbnailUtils.OPTIONS_RECYCLE_INPUT等
kind: MediaStore.Images.Thumbnails.* | MediaStore.Video.Thumbnails.*MICRO_KIND 96 * 96的縮略圖
MINI_KIND:512*384的縮略圖、
FULL_SCREEN_KIND:完整大小的圖片
const MediaStore = plus.android.importClass('android.provider.MediaStore');
const ThumbnailUtils = plus.android.importClass('android.media.ThumbnailUtils');
const filePath = "/storage/emulated/0/Movies/QQ視頻_2fac0bc06be7d09476f952d4d259ae471641725653.mp4";
let bitmap = ThumbnailUtils.createVideoThumbnail(filePath, MediaStore.Video.Thumbnails.MINI_KIND);
bitmap = ThumbnailUtils.extractThumbnail(bitmap, 90, 90, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
plus.android.invoke(bitmap, "recycle")
-
MediaMetadataRetriever
/**
* @method getVideoThumbnail
* @description 獲取視頻的縮略圖
* */
getVideoThumbnail: function(path) {
// 必須要先獲取到存儲(chǔ)權(quán)限才能使用
const Main = plus.android.runtimeMainActivity(); // 此處相當(dāng)于 context
const Build = plus.android.importClass('android.os.Build');
const MediaMetadataRetriever = plus.android.importClass("android.media.MediaMetadataRetriever");
const retriever = new MediaMetadataRetriever();
const hashMap = plus.android.importClass("java.util.HashMap");
const Url = plus.android.importClass("android.net.Uri");
const File = plus.android.importClass("java.io.File"); // 導(dǎo)入包并new這個(gè)類
const FileProvider = plus.android.importClass("android.support.v4.content.FileProvider");
const filePath = "/storage/emulated/0/Movies/QQ視頻_2fac0bc06be7d09476f952d4d259ae471641725653.mp4"
// 判斷是否是本地文件 ? 根據(jù)文件路徑獲取縮略圖 : 根據(jù)網(wǎng)絡(luò)路徑獲取縮略圖
// 判斷是否是網(wǎng)絡(luò)資源
// const isValidUrl = (string) => {
// try {
// new URL(string);
// return true;
// } catch (_) {
// return false;
// }
// }
const reg = /^https?/ig;
if(reg.test(filePath)){
plus.android.invoke(retriever, 'setMode', MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY)
// retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY);
// retriever.setDataSource(Main, Url.fromFile(new File(filePath)));
retriever.setDataSource(filePath);
// if(Build.VERSION.SDK_INT >= 24) {
// retriever.setDataSource( Main, FileProvider.getUriForFile( this, "uni.UNICB2E32F.provider", new File(filePath)));
// } else {
// retriever.setDataSource(Main, Url.fromFile(new File(filePath)))
// }
} else {
retriever.setDataSource("視頻鏈接",new hashMap());
}
// const bim = retriever.captureFrame();
const bim = retriever.getFrameAtTime(parseInt(0));// 獲取 第一幀 0 表示首幀圖片
// bim.recycle();
console.log(plus.android.invoke(bim, "getByteCount")/1024);
// retriever.getScaledFrameAtTime(-1, OPTION_CLOSEST_SYNC,512,512); // 指定縮略圖大小 512 * 512
// retriever.getFrameAtTime() // 正常
// retriever.getFrameAtTime( parseInt(1), MediaMetadataRetriever.OPTION_CLOSEST_SYNC)
// retriever.frameAtTime // 報(bào) undefind
// console.log();
// let u = retriever.getFrameAtTime(-1)
// let u = retriever.getScaledFrameAtTime(-1 , MediaMetadataRetriever.OPTION_CLOSEST_SYNC, 100 , 100)
// console.log(Bytes);
plus.android.invoke(bim, "recycle")
retriever.release()
},
-
Thumbnails
android.provider.MediaStore.Images.Thumbnails 和 android.provider.MediaStore.Video.Thumbnails
在安卓 29 MediaStore.Video.Thumbnails 已經(jīng)被改成了 ContentResolver#loadThumbnail
-
寫法一 getThumbnail()
// 使用 MediaStore.Video.Thumbnails.getThumbnail() 圖片的話和這個(gè)差不多 將id換成需要的圖片id將video 換成 image
const Main = plus.android.runtimeMainActivity(); // 此處相當(dāng)于 context
const MediaStore = plus.android.importClass('android.provider.MediaStore');
const media_id = '24571'
const resolver = Main.getContentResolver();
const bitmap = MediaStore.Video.Thumbnails.getThumbnail(resolver, Number(media_id), MediaStore.Video.Thumbnails.MINI_KIND, null);
-
寫法二 查詢數(shù)據(jù)庫(kù)
const MediaStore = plus.android.importClass('android.provider.MediaStore');
const thumbColumns = [
MediaStore.Video.Thumbnails.DATA,
MediaStore.Video.Thumbnails.VIDEO_ID
];
const Resolver = Main.getContentResolver(); // 獲取ContentResolver實(shí)例
plus.android.importClass(Resolver);
// MediaStore.Video.Thumbnails.VIDEO_ID + "=" + '24571' 后面這個(gè) 24571是視頻的id 而且查詢縮略圖必須要有條件 不然返回的是null
const cursor = Resolver.query(MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI, thumbColumns, MediaStore.Video.Thumbnails.VIDEO_ID + "=" + '24571', null, null);
plus.android.importClass(cursor);
// 此處使用 do {} while() 的原因是 cursor !=null && cursor.moveToNext() 單獨(dú)輸出都是true 取且之后確實(shí) false
do {
const _id = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Thumbnails.VIDEO_ID));
const fileParh = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Video.Thumbnails.DATA));
} while(cursor !=null && cursor.moveToNext())
cursor.close(); // 關(guān)閉游標(biāo)
-
解決新視頻或圖片縮略圖為 null
const Main = plus.android.runtimeMainActivity(); // 此處相當(dāng)于 context
const Intent = plus.android.importClass("android.content.Intent"); // 導(dǎo)入 Intent
const mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
const File = plus.android.importClass("java.io.File"); // 導(dǎo)入包并new這個(gè)類
const FileProvider = plus.android.importClass("android.support.v4.content.FileProvider");
const filePath = ""
const contentUri = FileProvider.getUriForFile( this, "uni.UNICB2E32F.provider", new File(filePath))
plus.android.invoke(mediaScanIntent , 'setData', contentUri);
plus.android.invoke(Main , 'sendBroadcast', mediaScanIntent);

浙公網(wǎng)安備 33010602011771號(hào)