首页 > 其他分享 >uniapp_04_获取缩略图的几种方法

uniapp_04_获取缩略图的几种方法

时间:2023-01-02 20:33:40浏览次数:70  
标签:uniapp const Thumbnails 04 缩略图 plus android MediaStore

关于 uniapp 获取缩略图

  • 前言
  • 获取图片缩略图
  • 获取视频缩略图
  • 参考文档

前言

项目中实现的一个文件管理功能,视频原本是列表的方式展示, 后来就在想是否可以让视频向图片一样排列显示一个缩略图而不是名称列表。
Android中,视频和图片都是有缩略图的我们可以直接获取

获取图片缩略图

获取图片的缩略图,我想到的方式有两种,
第二种方式与下面视频缩略图获取基本相同所以在此不做过多描述

  1. 压缩图片

利用BitmapFactory中的decodeFile对图片进行压缩

  1. 从媒体数据库查询

android.provider.MediaStore.Images.Thumbnails

获取视频缩略图

  1. ThumbnailUtils

ThumbnailUtils 是安卓2.2添加的方法, 三个静态方法
createVideoThumbnail(path, kind) 创建视频缩略图
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")
  1. MediaMetadataRetriever

/**
 * @method getVideoThumbnail
 * @description 获取视频的缩略图
 * */
getVideoThumbnail: function(path) {
  // 必须要先获取到存储权限才能使用
  const Main = plus.android.runtimeMainActivity(); // 此处相当于 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"); // 导入包并new这个类
  const FileProvider = plus.android.importClass("android.support.v4.content.FileProvider");
  const filePath = "/storage/emulated/0/Movies/QQ视频_2fac0bc06be7d09476f952d4d259ae471641725653.mp4"
  // 判断是否是本地文件 ? 根据文件路径获取缩略图 : 根据网络路径获取缩略图
  // 判断是否是网络资源
  // 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 // 报 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()
},
  1. Thumbnails

android.provider.MediaStore.Images.Thumbnails 和 android.provider.MediaStore.Video.Thumbnails
在安卓 29 MediaStore.Video.Thumbnails 已经被改成了 ContentResolver#loadThumbnail

  • 写法一 getThumbnail()
// 使用 MediaStore.Video.Thumbnails.getThumbnail() 图片的话和这个差不多 将id换成需要的图片id将video 换成 image
const Main = plus.android.runtimeMainActivity(); // 此处相当于 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);
  • 写法二 查询数据库
const MediaStore = plus.android.importClass('android.provider.MediaStore');
const thumbColumns = [
  MediaStore.Video.Thumbnails.DATA,
  MediaStore.Video.Thumbnails.VIDEO_ID
];
const Resolver = Main.getContentResolver(); // 获取ContentResolver实例
plus.android.importClass(Resolver);
//  MediaStore.Video.Thumbnails.VIDEO_ID + "=" + '24571' 后面这个 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() 单独输出都是true 取且之后确实 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(); // 关闭游标
  1. 解决新视频或图片缩略图为 null

const Main = plus.android.runtimeMainActivity(); // 此处相当于 context
const Intent = plus.android.importClass("android.content.Intent"); // 导入 Intent
const mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
const File = plus.android.importClass("java.io.File"); // 导入包并new这个类
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);

参考文档

标签:uniapp,const,Thumbnails,04,缩略图,plus,android,MediaStore
From: https://www.cnblogs.com/tsuru/p/16996449.html

相关文章

  • 04使用Pinia实现Vuex项目全球化
    在上一章中使用的Vuex作为状态管理实现的全球化,这篇文章使用Pinia作为状态管理。现有用户可能对Vuex更熟悉,它是Vue之前的官方状态管理库。由于Pinia在生态系统中能......
  • 最完美WIN10_Pro_22H2.19045.2364软件选装纯净版VIP38.3
    [系统简介】=============================================================1.本次更新母盘来WIN10_Pro_22H2.19045.2364。进一步优化调整。2.不支持更新,更新后精简版更新......
  • 我的收藏周刊 040
    文章分享公共DNS服务器IP地址比较全的公共DNS服务器IP地址UnderstandinghowFacebookdisappearedfromtheInternetUnderstandinghowFacebookdisapp......
  • 力扣104 求二叉树的最大深度
    力扣104求二叉树的最大深度题目:给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明:叶子节点是指没有子节点的节点。示......
  • 力扣1047 删除字符串中的所有相邻重复项
    题目:给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。在S上反复执行重复项删除操作,直到无法继续删除。在完成所有重复项删除操......
  • Codeforces 204 A. Pride 做题记录
    原题链接:https://codeforces.com/problemset/problem/204/A一开始还很若智地宕机了一下,想清楚了就很明白。很显然在不考虑首尾的情况下,题目要求的数字会以$10$为......
  • OneStack:Ubuntu 12.04 (或11.10) 一键安装部署OpenStack云计算平台
     OneStack:在Ubuntu12.04(precise)上一键安装部署OpentackEssex提醒:如果你喜欢折腾,喜欢自己一步一步安装各个功能组件和配置conf文件,你可以略过此文。本文工具可以在裸机和虚......
  • [20210429更新]软件方法(下)分析和设计 第8章 连载
    墙上挂了根长藤,长藤上面挂铜铃《长藤挂铜铃》;词:元庸,曲:梅翁(姚敏),唱:逸敏,1959您在阅读《软件方法》时如果发现错误,欢迎通过微信umlchina2告知。如果作者认为有道理,决定在下一次......
  • 联想小新+Windows10+Ubuntu18.04双系统安装+引导设置过程全记录
    写在前面双系统安装配置主要过程引导设置主要参考Ubuntu卸载需要的工具具体步骤情况一情况二主要参考后记2020.5.29更新关于卸载关于主题的配置写在前面又是折腾的一天,双系......
  • 04.关于线程你必须知道的8个问题(下)
    今天我们来学习线程中最后4个问题:线程的同步与互斥线程的本质与调度死锁的产生与解决多线程的是与非通过本篇文章,你可以了解到计算机中经典的同步机制--管程,Java线......