vue中使用canvas压缩图片上传

vue中使用canvas压缩图片上传

直接上代码,以备后查或者ctrl+c ,嘿嘿
有疑问可留言

压缩原理

  • 使用canvas压缩图片,涉及到一些对象的转换,比如file对象转换成dataUrl
  • blob 对象转换成file对象
  • 使用axios实现上传

其中的一些方法复制即用,无需修改

全部代码如下

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>阿凡提汽配汽修平台</title>
    <link rel="stylesheet" href="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/css/vant.css">
    <link rel="stylesheet" href="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/css/common.css">
    <link rel="stylesheet" href="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/css/publishpage.css">
    <script src="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/js/vue.min.js"></script>
    <script src="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/js/vant.min.js"></script>
    <script src="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/js/axios.min.js"></script>
    <!-- <script src="https://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/static/js/common.js?v=2"></script> -->
    <style>
        .van-index-anchor {
            background-color: #ccc;
            padding: 0 3vw !important;
            height: 5vw !important;
            line-height: 5vw !important;
            font-size: 3vw !important;
        }
      img{
width:100%;
}
        .container {
            width: 0;
            height: 0;
            overflow: hidden;
        }

        canvas {
            border: 1px solid #000;
        }
    </style>

</head>

<body>
    <div class="container">
        <canvas width="0" height="0"></canvas>
    </div>
    <div id="app">
        <div class="publish-page">
            <div class="nav">
                <image class="nav-img"
                    src="http://fallsheep-bost-aft.oss-cn-beijing.aliyuncs.com/icon/icon/ico_zuo.png"></img>
                    <div class="nav-title">发布信息</div>
            </div>
            <div class="nav-null-box"></div>
            <p>测试</p>

            <van-uploader v-model="fileList" multiple max-count="3"></van-uploader>
            <van-button @click="toSubmit">上传</van-button>
            <img :src="myImg" alt="hehe">
        </div>

    </div>
    <script>

        var app = new Vue({
            el: '#app',
            data: {
                fileList: [],
                myImg: '',
                imgNum: null,
            },
            methods: {
                // 上传图片
                toSubmit() {
                    this.toCanvas()
                },
                toCanvas() {
                    var _this = this
                    this.imgNum = this.fileList.length
                    if (this.fileList && this.fileList.length > 0) {
                        for (var i = 0; i < this.fileList.length; i++) {
                            console.log(this.fileList[i].file)
                            var imgName = this.fileList[i].file.name
                            var imgType = this.fileList[i].file.type
                            this.readFileAsDataURL(this.fileList[i].file, function (imgurl) {
                                _this.myImg = imgurl
                                var image = new Image()
                                image.src = imgurl
                                image.onload = function () {
                                    var myCanvas = document.querySelector('canvas')
                                    var ctx = myCanvas.getContext('2d')
                                    var imageWidth = image.width
                                    var imageHeight = image.height
                                    //定义压缩后的宽度,也可封装后调用时传入
                                    var img_width = 750 //此处的750是压缩后图片的宽度,也是canvas画布的宽度
                                    //宽度750 ,通过计算可得出缩放后的高
                                    myCanvas.height = img_width * imageHeight / imageWidth
                                    myCanvas.width = img_width
                                    ctx.drawImage(image, 0, 0, imageWidth, imageHeight, 0, 0, img_width, img_width * imageHeight / imageWidth)
                                    var bloburl = myCanvas.toDataURL(imgType);
                                    var blob = _this.dataURLtoBlob(bloburl);
                                    // let files = ([this.blob], file.name, {type: file.type})
                                    // blob = _this.blobToFile(blob ,imgName)
                                    var file = _this.blobToFile(blob, imgName)

                                    let files = new window.File([blob], imgName, { type: imgType })
                                    console.log(files)
                                    _this.uploadfile(file, 0, '测试', function (im) { //括号中是一些测试的数据
                                        _this.tips = '第' + im + "张图片上传成功"
                                    }, i)
                                }
                            })
                        }
                    } else {
                        this.step = 6;
                        this.num = 3;
                        this.modelShow = false
                    }
                },
                readFileAsDataURL(file, callback) {
                    var a = new FileReader();
                    a.readAsDataURL(file);
                    a.onload = function (e) { callback(e.target.result); };
                },
                //将base64转换为blob
                dataURLtoBlob: function (dataurl) {
                    var arr = dataurl.split(','),
                        mime = arr[0].match(/:(.*?);/)[1],
                        bstr = atob(arr[1]),
                        n = bstr.length,
                        u8arr = new Uint8Array(n);
                    while (n--) {
                        u8arr[n] = bstr.charCodeAt(n);
                    }
                    return new Blob([u8arr], { type: mime });
                },
                //将blob转换为file
                blobToFile: function (theBlob, fileName) {
                    theBlob.lastModifiedDate = new Date();
                    theBlob.name = fileName;
                    return theBlob;
                },
                uploadfile(file, id, name, callback, i) {
                    var _this = this
                    let fd = new FormData();
                    fd.append("file", file);
                    fd.append("name", name);
                    fd.append("type_id", id);
                    axios.post("https://www.xxx.com/xxx/xxx", fd, { //https://www.xxx.com/xxx/xxx对应自己的接口
                        headers: {
                            "Content-Type": "multipart/form-data",
                            charset: "UTF-8"
                        },
                        transformRequest: [
                            function () {
                                return fd;
                            }
                        ]
                    }).then(function () {
                        callback(i)
                        _this.imgNum--
                        if (_this.imgNum <= 0) {
                            _this.step = 6;
                            _this.num = 3;
                            _this.modelShow = false
                        }
                    })
                },
            },
            created() {

            }
        })
    </script>
</body>

</html>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345