video / image上传操作-校验、截取首帧和正方形预览图等

常见video / image上传操作-校验、截取首帧和正方形预览图等。

上回搞了一个视频和图片上传和校验的需求,感觉学到很多,一些常见的函数记录如下:

1. 图片校验尺寸
const { maxCount = 30, maxWidth, maxHeight, minHeight = 200, minWidth = 200 } = props;
// 文件个数和内存大小、格式可以提前校验,不用请求图片信息。

const reader = new FileReader();
reader.readAsDataURL(file);
// eslint-disable-next-line no-loop-func
reader.onload = (e) => {
  const img = new Image();
  img.src = e.target.result;
  img.onload = () => {
    const width = img.width;
    const height = img.height;
    if (
      (maxWidth && width > maxWidth) ||
      (maxHeight && height > maxHeight) ||
      (minWidth && width < minWidth) ||
      (minHeight && height < minHeight)
    ) {
     resolve(false);
    } else {
      // 通过全部校验,处理图片
      resolve(true)
    }
  };
};
2. 视频校验尺寸

需要了解一下视频加载中的触发事件顺序。
参考:
https://guste.github.io/2018/07/24/video%E6%A0%87%E7%AD%BE%E4%BA%8B%E4%BB%B6%E6%8C%87%E5%8C%97/

  const { maxCount = 30, maxWidth, maxHeight, minHeight = 200, minWidth = 200 } = props;
  // 文件个数和内存大小、格式可以提前校验,不用请求图片信息。
  // 视频请求文件信息用createObjectURL
  
  let video = document.createElement('video');
  video.currentTime = 1; // 取封面首帧需要currentTime=1
  video.src = window.URL.createObjectURL(file);
  // 获取视频的元数据,但是文件不一定加载出来,此处可以进行校验
  video.addEventListener('loadedmetadata', (e) => {
    if (
      (maxWidth && video.videoWidth > maxWidth) ||
      (maxHeight && video.videoHeight > maxHeight) ||
      (minWidth && video.videoWidth < minWidth) ||
      (minHeight && video.videoHeight < minHeight) ||
      (maxDuration && video.duration > maxDuration)
    ) {
      resolve(false)
    } else {
      // 进行下一步 loadeddata 事件,取封面首帧
      // 此时视频画面信息不一定加载出来,取出来的画面是纯黑色。
    }
  });
  // 校验完毕,处理封面图和展示图
  video.addEventListener('loadeddata', (e) => {
	// 为了保险可以在这里再校验一次,不通过的resolve(false)
	// 取首帧,函数附下。
	const poster = getVideoPoster(video)
  });
  };
3. 视频截取第一帧

参考:https://juejin.cn/post/6844903933631004679
此处注意一个小坑:video视频设置currentTime不起作用?(我们要求视频出现需要跳转开头),但是设置currentTime=0不起作用,后面经过一番搜索,设置成currentTime=‘0’才能达到效果。要赋值字符串才行。

web前端处理图片首选当然是canvas。

// 注意传入的video是上文中已经赋值了src的DOM节点,并且设置currentTime=1。
// 存在有文章说即使在loadeddata事件中仍然截取为黑色,可以尝试将video属性赋值“muted” "autoplay" “preload”,因为在chrome中只有静音的视频才能自动播放,这样截取出的第一帧就会有值。

  getVideoPoster = (video) => {
    const canvas = document.createElement('canvas');
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
    return canvas.toDataURL('image/jpg', 1);
  };

完整截取的上传函数如下:
onChange = (e)=>{
  const uploadFiles = e.target.files?.[0] || {};
  let video = document.createElement('video');
  video.currentTime = '1'; // 取封面首帧需要currentTime=1
  video.src = window.URL.createObjectURL(file);
  video.addEventListener('loadeddata', (e) => {
	const poster = getVideoPoster(video)
  });
}

4. 截图方形预览图(视频 / 图片通用)

上文中已经截取到了base64格式的视频首帧,因此预览图从封面中截取,此处截取的规则如下:图片自适应在封面(设置为200*200)大小,短的那一条边和200px等宽,全部取用,而更长的那一条边取居中长度裁剪。(这么说不知道能不能形容清楚)
在裁剪之前简单介绍一下canvas裁剪的函数,其实还是靠最基本的drawImage。
ctx.drawImage(绘画对象, x, y, imageSizeX, imageSizeY, canvasX, canvasY, canvasSizeX, canvasSizeY);
使用这个函数的含义:
将绘画对象花在画布上,首先从绘画对象的(x,y)坐标开始,横着沿x轴画一条imageSizeX这么长的线,然后再纵向沿着y轴画一条imageSizeY这么长的线,我们就在【原图】上画了一个长方形。
然后把这个长方形放进canvas里
在这里插入图片描述

  // 可以是imgDom或者videoDom,Dom节点就是上文中我们创建的节点对象。
  squareImage = (imgDom) => {
    const width = imgDom.videoWidth || imgDom.width;
    const height = imgDom.videoHeight || imgDom.height;
    const canvasSize = 200;
    var size = Math.min(width, height);

    const canvas = document.createElement('canvas');
    canvas.width = canvasSize;
    canvas.height = canvasSize;
    const ctx = canvas.getContext('2d');
    const offsetX = width >= height ? (width - size) / 2 : 0;
    const offsetY = width >= height ? 0 : (height - size) / 2;

    ctx.drawImage(imgDom, offsetX, offsetY, size, size, 0, 0, canvasSize, canvasSize);
    return canvas.toDataURL('image/jpg', 0.9);
  };
5. 图片压缩

参考之前的调研文章

  compressImage = (img) => {
    const canvas = document.createElement('canvas');
    canvas.width = img.width;
    canvas.height = img.height;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0, img.width, img.height);
    return canvas.toDataURL('image/jpg', 0.7);
  };
6. base64转二进制字节流上传
  dataURItoFile = (dataURI) => {
    var byteString = atob(dataURI.split(',')[1]);
    var ab = new ArrayBuffer(byteString.length);
    var ia = new Uint8Array(ab);
    for (let i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ab], { type: 'image/png' });
  };

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/378917.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java基础知识练习题

1.对Java源文件进行编译操作的命令是&#xff08;B&#xff09; A.Java B.javac C.where is java D.javaw 2.下列命令中&#xff0c;用来运行Java程序的是&#xff08;A&#xff09;A.java B. javadoc C. jar D. javac 分析&#xff1a; 对Java源程序进行编译的命令是J…

力扣102. 二叉树的层序遍历 (复习vector和queue的常见用法

目录 题目描述 题目解析 题目答案 题目所用知识点 最后 题目描述 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术…

使用pygame生成红包封面

import pygame import sys# 初始化pygame pygame.init()# 设置红包封面尺寸 size width, height 640, 960 screen_color (255, 0, 0) # 红色背景# 创建窗口 screen pygame.display.set_mode(size) pygame.display.set_caption(红包封面)# 加载龙形图片 dragon_image pygam…

一些参数(仅供个人理解)

1.mAP&#xff1a; 数据集的平均准确率 mAP50-95&#xff1a;mAP阈值为50到mAP阈值为95&#xff0c;间隔5%,取得10个mAP值&#xff0c;然后对这十个值取平均。 目标检测评估指标mAP&#xff1a;从Precision,Recall,到AP50-95【未完待续】_map50和map50-95-CSDN博客 2.IoU&a…

JVM调优(Window下)

1、编写代码&#xff0c;像下面代码这样&#xff0c;产生OOM&#xff0c; private static final Integer K 1024;/*** 死循环&#xff0c;验证JVM调优* return*/GetMapping(value "/deadLoop")public void deadLoop(){int size K * K * 8;List<byte[]> lis…

C语言第二十一弹---指针(五)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 转移表 1、转移表 总结 1、转移表 函数指针数组的用途&#xff1a;转移表 举例&#xff1a;计算器的⼀般实现&#xff1a; 假设我们需要做一个能够进行加减…

Flume拦截器使用-实现分表、解决零点漂移等

1.场景分析 使用flume做数据传输时&#xff0c;可能遇到将一个数据流中的多张表分别保存到各自位置的问题&#xff0c;同时由于采集时间和数据实际发生时间存在差异&#xff0c;因此需要根据数据实际发生时间进行分区保存。 鉴于此&#xff0c;需要设计flume拦截器配置conf文件…

C#,佩尔数(Pell Number)的算法与源代码

1 佩尔数&#xff08;Pell Number&#xff09; 佩尔数&#xff08;Pell Number&#xff09;是一个自古以来就知道的整数数列&#xff0c;由递推关系定义&#xff0c;与斐波那契数类似。佩尔数呈指数增长&#xff0c;增长速率与白银比的幂成正比。它出现在2的算术平方根的近似值…

一图窥探RAG技术发展现状

2023年除了大语言模型&#xff0c;听到最多的当属RAG&#xff08;检索增强生成技术了&#xff09;&#xff0c;在实际业务场景落地过程中&#xff0c;由于大模型目前的一定局限和能力现状以及Token限制、训练成本等多种因素的影响下&#xff0c;RAG不得不成为大家选择快速试错、…

WebSocket+Http实现功能加成

WebSocketHttp实现功能加成 前言 首先&#xff0c;WebSocket和HTTP是两种不同的协议&#xff0c;它们在设计和用途上有一些显著的区别。以下是它们的主要特点和区别&#xff1a; HTTP (HyperText Transfer Protocol): 请求-响应模型&#xff1a; HTTP 是基于请求-响应模型的协…

Three.js学习8:基础贴图

一、贴图 贴图&#xff08;Texture Mapping&#xff09;&#xff0c;也翻译为纹理映射&#xff0c;“贴图”这个翻译更直观。 贴图&#xff0c;就是把图片贴在 3D 物体材质的表面&#xff0c;让它具有一定的纹理&#xff0c;来为 3D 物体添加细节的一种方法。这使我们能够添加…

TCP和UDP相关问题(重点)——7.TCP的流量控制怎么实现的?

流量控制就是在双方通信时&#xff0c;发送方的速率和接收方的速率不一定是相等的&#xff0c;如果发送方发送的太快&#xff0c;接收方就只能把数据先放到接收缓冲区中&#xff0c;如果缓冲区都满了&#xff0c;那么处理不过来就只能丢弃&#xff0c;所以需要控制发送方的速率…

【Go】三、Go并发编程

并发编程 我们主流的并发编程思路一般有&#xff1a;多进程、多线程 但这两种方式都需要操作系统介入&#xff0c;进入内核态&#xff0c;是十分大的时间开销 由此而来&#xff0c;一个解决该需求的技术出现了&#xff1a;用户级线程&#xff0c;也叫做 绿程、轻量级线程、协…

猫头虎分享已解决Bug || Spring Error: Request method ‘POST‘ not supported

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

06-OpenFeign-使用HtppClient连接池

默认下OpenFeign使用URLConnection 请求连接&#xff0c;每次都需要创建、销毁连接 1、添加ApacheHttpClient依赖 <!-- 使用Apache HttpClient替换Feign原生httpclient--><dependency><groupId>org.apache.httpcomponents</groupId><artifact…

springboo冬奥会科普平台源码和论文

随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理平台应运而生&#xff0c;各行各业相继进入信息管理时代&#xf…

EMC学习笔记(二十二)降低EMI的PCB设计指南(二)

降低EMI的PCB设计指南&#xff08;二&#xff09; 1.电源和地概述2.电感量3.两层板和四层板4.单层和双层设计中的微控制器接地5.信号返回地6.模拟、数字信号与大功率电源7.模拟电源引脚和模拟参考电源8.四层板电源设计参考注意事项 tips&#xff1a;资料主要来自网络&#xff0…

Apache网站部署

站点添加及linux防火墙和selinux启动和停止 apache站点添加 linux系统防火墙和selinux起停 1、防火墙firewall操作 查看防火墙的状态&#xff0c;如下&#xff08;默认开启&#xff09;&#xff1a; systemctl status firewalld 关闭服务 systemctl stop firewalld 关闭…

《向量数据库指南》——Milvus Cloud「删除」:眼见未必为实

“执行 Collection 中的 delete 操作后,再次调用 num_entities 检查集合中的数据的条数,和删除前一致, delete 不能从物理层面上删除数据吗?”“删除的数据还能被查到是为什么?”“请问下删除 collection 后,磁盘大小没有恢复,该怎么处理?”社区中关于“删除”讨论最多…

EMC学习笔记(二十一)降低EMI的PCB设计指南(一)

降低EMI的PCB设计指南&#xff08;一&#xff09; 1.概述2.射频3.连接器与过孔元件4.静态引脚和动态引脚和输入5.基本回路6.差模与共模 tips&#xff1a;资料主要来自网络&#xff0c;仅供学习使用。 1.概述 印刷电路板(PCB)的一般布局准则&#xff0c;基本上都有相对的文件进…
最新文章