TypechoJoeTheme

Dcr163的博客

统计

Vant2.x上传图片并且压缩

2022-02-18
/
0 评论
/
1,257 阅读
/
正在检测是否收录...
02/18

废话不多说直接上代码

<!DOCTYPE html>
<html lang="zh-cn">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.12/lib/index.css" />
        <title>Vant2</title>
    </head>
    <body>
        <div id="app">

            <van-field name="uploader" label="文件上传">
                <template #input>
                    <van-uploader v-model="fileList" :after-read="afterRead" :max-count="10" accept="image/*" :multiple="false" />
                </template>
            </van-field>
        </div>

        <!-- 引入 Vue 和 Vant 的 JS 文件 -->
        <!-- <script src="https://cdn.jsdelivr.net/npm/vue@2.6/dist/vue.min.js"></script> -->
        <script src="vue.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/vant@2.12/lib/vant.min.js"></script>
        <script>
            // 在 #app 标签下渲染一个按钮组件
            const app = new Vue({
                el: '#app',
                data() {
                    return {
                        quality: 0.8, //图片压缩质量
                        fileList: [],
                    }
                },
                methods: {
                    afterRead(file) {
                        let _this = this;
                        // file.status = 'uploading';
                        // file.message = '上传中...';
                        const trueFile = file.file;
                        const size = trueFile.size / 1024;
                        console.log(`压缩前 ===>${size}k`);
                        //图片并且大于800k开始压缩
                        if (/^image/.test(trueFile.type) && size >= 800) {
                            // 创建一个reader
                            let reader = new FileReader();
                            // 将图片2将转成 base64 格式
                            reader.readAsDataURL(trueFile);
                            // 读取成功后的回调
                            reader.onloadend = function() {
                                let result = this.result;
                                let img = new Image();
                                img.src = result;
                                img.onload = function() {
                                    // 压缩
                                    let data = _this.compress(img, trueFile.name, trueFile.type);
                                    console.log(`压缩后 ===>${data.fileData.size/1024}k`);
                                    file.content = data.base64Data;
                                    file.file = data.fileData;
                                }
                            }
                        }
                    },
                    // 压缩图片
                    compress(img, name, type) {
                        let canvas = document.createElement('canvas');
                        let ctx = canvas.getContext('2d');
                        //瓦片canvas
                        let tCanvas = document.createElement('canvas');
                        let tctx = tCanvas.getContext('2d');
                        // let initSize = img.src.length;
                        let width = img.width;
                        let height = img.height;
                        //如果图片大于四百万像素,计算压缩比并将大小压至400万以下
                        let ratio;
                        if ((ratio = (width * height) / 4000000) > 1) {
                            // console.log("大于400万像素");
                            ratio = Math.sqrt(ratio);
                            width /= ratio;
                            height /= ratio;
                        } else {
                            ratio = 1;
                        }
                        canvas.width = width;
                        canvas.height = height;
                        //    铺底色
                        ctx.fillStyle = '#fff';
                        ctx.fillRect(0, 0, canvas.width, canvas.height);
                        //如果图片像素大于100万则使用瓦片绘制
                        let count;
                        if ((count = (width * height) / 1000000) > 1) {
                            //console.log("超过100W像素");
                            count = ~~(Math.sqrt(count) + 1) //计算要分成多少块瓦片
                            //计算每块瓦片的宽和高
                            let nw = ~~(width / count);
                            let nh = ~~(height / count);
                            tCanvas.width = nw;
                            tCanvas.height = nh;
                            for (let i = 0; i < count; i++) {
                                for (let j = 0; j < count; j++) {
                                    tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio,
                                        0, 0, nw, nh);
                                    ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
                                }
                            }
                        } else {
                            ctx.drawImage(img, 0, 0, width, height);
                        }
                        //进行压缩 
                        let ndata = canvas.toDataURL('image/jpeg', this.quality);
                        tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
                        return {
                            base64Data: ndata,
                            fileData: this.dataURLtoFile(ndata, name, type)
                        }
                    },
                    //将base64转换为文件
                    dataURLtoFile(dataurl, name, type) {
                        name = name ? name : '图片';
                        type = type ? type : 'jpg';
                        var arr = dataurl.split(','),
                            bstr = atob(arr[1]),
                            n = bstr.length,
                            u8arr = new Uint8Array(n);
                        while (n--) {
                            u8arr[n] = bstr.charCodeAt(n);
                        }
                        return new File([u8arr], name, {
                            type: type
                        })
                    },
                }
            });
            // 通过 CDN 引入时不会自动注册 Lazyload 组件
            // 可以通过下面的方式手动注册
            Vue.use(vant.Lazyload);
        </script>
</html>

执行结果如图所示

代码都有注释,可以直接拿下来使用!

VUEvant上传
朗读
赞(0)
版权属于:

Dcr163的博客

本文链接:

https://dcr163.cn/618.html(转载时请注明本文出处及文章链接)

评论 (0)