get两个js小技能——JS截取视频第一帧&图片转Base64

2023-03-23 21:16:11 浏览数 (1)

背景

由于开发之前做的VisualDrag拖拽模板优化的时候,拖拽进去的图片、视频文件等需要进行截图作为封面,目前采用的截图方法是htme2canvas,使用canvas进行的截图操作,所以就会遇到这样的问题,视频和图片图床简单的使用标签加入canvas画布里面无法正确的截图成功。最后采取的措施就是将图片转为base64画入canvas,将视频截取第一帧图片,然后画进canvas,最后进行截图,最后经过折腾,这个方法好像成功了,写这篇博客进行记录下。

JS截取视频第一帧

截取视频的第一帧作为视频的封面是一个很常见的视频上传的做法。但这种做法一般会在上传进服务器时,在服务器进行截图了,这个操作方法在我之前的博客上有介绍过:https://qkongtao.cn/?p=560#h2-4

但是前端有时候为了避免浪费服务器资源,可以在前端使用js直接进行截图了。

代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>js截取视频第一帧</title>
</head>

<body>
    <div>
        <button onclick="cutImage()">截取视频第一帧</button>
    </div>
    <div>
        <!-- 注意跨域画布污染 -->
        <video width="640" height="480" src="https://upyun.qkongtao.cn/kodbox/视频/20221016134256839.mp4"
            controls="controls" id="fileVideo" crossorigin="anonymous">您的浏览器不支持视频播放</video>
        <div>
            <p>视频第一帧:</p> <img
                src="https://upyun.qkongtao.cn/kodbox/视频/upload.png?_upt=5b974ef11679068799"
                id="videoImg">
        </div>
    </div>

</body>

<script>
    function cutImage() {
        // 获取音频标签
        let video = document.getElementById('fileVideo')
        video.currentTime = 2 // 第一帧
        video.oncanplay = () => {
            let canvas = document.createElement("canvas");
            let ctx = canvas.getContext('2d') // 绘制2d
            canvas.width = video.clientWidth // 获取视频宽度
            canvas.height = video.clientHeight // 获取视频高度
            // 利用canvas对象方法绘图
            ctx.drawImage(video, 0, 0, video.clientWidth, video.clientHeight)
            // 转换成base64形式
            let imgUrl = canvas.toDataURL("image/png");
            console.log('imgUrl :>> ', imgUrl);
            document.getElementById("videoImg").src = imgUrl
        }
    }
</script>

</html>

效果如下:

需要注意的地方是视频资源跨域导致画布污染的问题,所以需要在video标签加上 crossorigin="anonymous" 。

如果需要截图第2帧以上则需要在video.oncanplay()方法中进行截图。

图片转Base64

在开发的很多场景中需要用到base64图片形式进行传输,这种一般会用在缩略图的小文件图片中,提高浏览器的流畅性。

当然在canvas画布中,当进行绘制图片时,最好还是先将图片img标签转换为base64之后进行drawImage(),避免画布被污染和跨域等问题。

代码如下:

代码语言:javascript复制
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>图片转Base64</title>
</head>

<body>
    <div>
        <button onclick="imgToBase64()">转换成base64形式</button>
    </div>
    <img id="img" src="http://upyun.qkongtao.cn/chevereto/2022/10/28/20210917152407654.jpg" alt="" width="300">
    <p>转换成base64形式</p>
    <div id="base64" style="word-break: break-all;"></div>
</body>

<script>
    function imgToBase64() {

        var src = document.getElementById("img").src
        getImageUrlBase64(src).then(
            (dataUrl) => {
                base64Url = dataUrl;
                console.log('base64Url :>> ', base64Url);

                document.getElementById("base64").innerHTML = base64Url
            }
        );
    }

    /**@url :图片服务器上的url
     * @img :图片url对应的图片
     * */
    function getImageUrlBase64(url) {
        return new Promise((resolve, reject) => {
            const img = new Image();
            img.crossOrigin = "anonymous"; //处理跨域
            img.src = url;
            img.onload = function () {
                const canvas = document.createElement("canvas"); //创建一个canvas元素
                canvas.width = img.width; //把当前url对应的图片的宽度赋予canvas
                canvas.height = img.height; //把当前url对应的图片的高度赋予canvas
                const ctx = canvas.getContext("2d");
                ctx.drawImage(img, 0, 0, canvas.width, canvas.height); //在画布上一比一的画出img
                const dataUrl = canvas.toDataURL("image/jpeg"); //调用canvas的toDataURL获取.jpg的base64数据
                resolve(dataUrl);
            };
        });
    }
</script>

</html>

效果如下:

0 人点赞