前端实现图片的上传

一、使用element-ui

代码如下:

<el-upload
  class="avatar-uploader"
  action="https://jsonplaceholder.typicode.com/posts/"
  :show-file-list="false"
  :on-success="handleAvatarSuccess"
  :before-upload="beforeAvatarUpload">
  <img v-if="imageUrl" :src="imageUrl" class="avatar">
  <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>

<style>
  .avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }
  .avatar-uploader .el-upload:hover {
    border-color: #409EFF;
  }
  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
  }
  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }
</style>

<script>
  export default {
    data() {
      return {
        imageUrl: ''
      };
    },
    methods: {
      handleAvatarSuccess(res, file) {
        this.imageUrl = URL.createObjectURL(file.raw);
      },
      beforeAvatarUpload(file) {
        const isJPG = file.type === 'image/jpeg';
        const isLt2M = file.size / 1024 / 1024 < 2;

        if (!isJPG) {
          this.$message.error('上传头像图片只能是 JPG 格式!');
        }
        if (!isLt2M) {
          this.$message.error('上传头像图片大小不能超过 2MB!');
        }
        return isJPG && isLt2M;
      }
    }
  }
</script>

上述action是提交图片的地址,若需要穿参数可以使用el-upload的属性headers,然后就可以了,下面会拿到imageUrl,然后绑定在页面,显示在页面上,就完成了图片上传的功能。

二、利用H5上传图片

<template>
    <div class="phone" for="upload" :class="{'card': useCategory === '3'}">
        <input type="file" id="upload" accept="image/*" @change="openPhone" style="opacity:0;">
        <img :src="headerImage" class="picture" alt="">
    </div>
</template>

<script>
    export default {
        name: 'phone',
        props: {
            useCategory: '',
            onThree: false,
            isFlag: false
        },
        data() {
            return {
                icValue: '',
                ocrResult: {},
                headerImage: '',
            }
        },
        methods: {
            openPhone(e) {
                if(!this.isFlag){
                    let files = e.target.files || e.dataTransfer.files
                    if (!files.length) return
                    this.picValue = files[0]
                    this.imgPreview(this.picValue)
                }
            },
            imgPreview(file) {
                let self = this
                let Orientation
                // 看支持不支持FileReader
                if (!file || !window.FileReader) return

                if (/^image/.test(file.type)) {
                    // 创建一个reader
                    let reader = new FileReader()
                    // 将图片2将转成 base64 格式
                    reader.readAsDataURL(file)
                    // 读取成功后的回调
                    reader.onloadend = function () {
                        let result = this.result
                        let img = new Image()
                        img.src = result
                        //判断图片是否大于100K,是就直接上传,反之压缩图片
                        if (this.result.length <= (1 * 1024)) {
                            self.headerImage = this.result
                            self.postImg(file)
                        } else {
                            img.onload = function () {
                                let data = self.compress(img, Orientation)
                                self.headerImage = data
                                let blob = self.dataURItoBlob(data)
                                self.postImg(blob)
                            }
                        }
                    }
                }
            },
            postImg (file) {
                //这里写接口
                let formData = new FormData()  // 创建form对象
                formData.append('file', file)  // 通过append向form对象添加数据
                formData.append('useCategory', this.useCategory)  // 如果还需要传替他参数的话
                formData.append('platform', 'ewx')  // 如果还需要传替他参数的话
                this.$ajax({
                    headers: {
                        'Content-Type': 'multipart/form-data'
                    },
                    type: 'openPhone',
                    method: 'POST',
                    data: formData
                }).then(res => {
                    console.log(res)
                    if( res.data.success) {
                        this.ocrResult = res.data.data.ocrResult
                        this.ocrResult.id = res.data.data.attach.id
                        this.ocrResult.url = res.data.data.attach.url
                        this.$emit('openPhone', this.ocrResult)
                    }else {
                        let msg
                        if(res.data.errExcep && res.data.errExcep != '') {
                            msg = res.data.errExcep
                        }else {
                            msg = res.data.errMsg
                        }
                        Toast({
                            message: msg,
                            duration: 2000
                        });
                    }
                })
            },
            rotateImg (img, direction,canvas) {

                //最小与最大旋转方向,图片旋转4次后回到原方向

                const min_step = 0

                const max_step = 3

                if (img == null)return;

                //img的高度和宽度不能在img元素隐藏后获取,否则会出错

                let height = img.height

                let width = img.width

                let step = 2

                if (step == null) {

                    step = min_step

                }

                if (direction == 'right') {

                    step++

                    //旋转到原位置,即超过最大值

                    step > max_step && (step = min_step)

                } else {

                    step--;

                    step < min_step && (step = max_step)

                }

                //旋转角度以弧度值为参数

                let degree = step * 90 * Math.PI / 180

                let ctx = canvas.getContext('2d')

                switch (step) {

                    case 0:

                        canvas.width = width

                        canvas.height = height

                        ctx.drawImage(img, 0, 0)

                        break

                    case 1:

                        canvas.width = height

                        canvas.height = width

                        ctx.rotate(degree)

                        ctx.drawImage(img, 0, -height)

                        break

                    case 2:

                        canvas.width = width

                        canvas.height = height

                        ctx.rotate(degree)

                        ctx.drawImage(img, -width, -height)

                        break

                    case 3:

                        canvas.width = height

                        canvas.height = width

                        ctx.rotate(degree)

                        ctx.drawImage(img, -width, 0)

                        break;

                }

            },
            compress(img,Orientation) {

                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)

                }

                //修复ios上传图片的时候 被旋转的问题

                if(Orientation != "" && Orientation != 1){

                    switch(Orientation){

                        case 6://需要顺时针(向左)90度旋转

                            this.rotateImg(img,'left',canvas)

                            break;

                        case 8://需要逆时针(向右)90度旋转

                            this.rotateImg(img,'right',canvas)

                            break;

                        case 3://需要180度旋转

                            this.rotateImg(img,'right',canvas) //转两次

                            this.rotateImg(img,'right',canvas);

                            break;

                    }

                }

                //进行最小压缩

                let ndata = canvas.toDataURL('image/jpeg', 0.1);

                console.log('压缩前:' + initSize);

                console.log('压缩后:' + ndata.length);

                console.log('压缩率:' + ~~(100 * (initSize - ndata.length) / initSize) + "%");

                tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;

                return ndata;

            },
            // base64转成bolb对象
            dataURItoBlob(base64Data) {
                var byteString;
                if (base64Data.split(",")[0].indexOf("base64") >= 0)
                    byteString = atob(base64Data.split(",")[1]);
                else byteString = unescape(base64Data.split(",")[1]);
                var mimeString = base64Data
                    .split(",")[0]
                    .split(":")[1]
                    .split(";")[0];
                var ia = new Uint8Array(byteString.length);
                for (var i = 0; i < byteString.length; i++) {
                    ia[i] = byteString.charCodeAt(i);
                }
                return new Blob([ia], { type: mimeString });
            }
        }
    }
</script>

<style lang="stylus" rel="stylesheet/stylus" scoped>
    .phone-box
        background #fff
        overflow hidden
    .info
        border-top 1px solid #E0E0E0
        background #fff
    #upload
        position absolute
        top: 0
        left 0
        right 0
        bottom 0
        width: 100%;
        height: 100%;
        z-index 10
    .picture
        position absolute
        top: 0
        left 0
        right 0
        bottom 0
        width: 100%;
        height: 100%;
        overflow: hidden;
        background-position: center center;
        background-repeat: no-repeat;
        background-size: cover;
        z-index 5
    .phone
        position relative
        width 100%
        height 3.26rem
        font-size .3rem
        background: #F3F5F7
        .top-l
            position absolute
            top 0
            left 0
            width .625rem
            height .625rem
            background: url(../assets/images/top-l.png) no-repeat
            background-size 100% 100%
            z-index 10
        .top-r
            position absolute
            top 0
            right 0
            width .625rem
            height .625rem
            background: url(../assets/images/top-r.png) no-repeat
            background-size 100% 100%
            z-index 10
        .bottom-l
            position absolute
            bottom 0
            left 0
            width .625rem
            height .625rem
            background: url(../assets/images/bottom-l.png) no-repeat
            background-size 100% 100%
            z-index 10
        .bottom-r
            position absolute
            bottom 0
            right 0
            width .625rem
            height .625rem
            background: url(../assets/images/bottom-r.png) no-repeat
            background-size 100% 100%
            z-index 10
    .phone.card
        width 100%
        height 4.48rem
        background: url(../assets/images/authentication-bg.png) no-repeat
        background-size 100% 100%
    .phone.wd-326
        width 3.26rem
    .input-call
        border-bottom 1px solid #E0E0E0
        padding .29rem .3rem
    .tit
        font-size .3rem
        color #49505A
    .no-phone
        padding-top .76rem
    .phone-icon
        width .66rem
        height .58rem
        background url(../assets/images/phone.png) no-repeat
        background-size 100% 100%
        margin-bottom .32rem
    .card .no-phone
        padding-top 1.36rem
</style>

猜你喜欢

转载自blog.csdn.net/zhanghuali0210/article/details/84373849
今日推荐