vue-cropper使用截图OSS上传

效果图:

vue-cropper使用截图OSS上传_第1张图片

前端页面需要引入


安装所需要的依赖

npm install vue-cropper
npm install ali-oss
npm install co

html代码展示

例子

download(base64) download(blob)

js代码展示

name: 'home',
        data() {
            return {
                model: false,
                modelSrc: '',
                crap: false,
                previews: {},
                lists: [
                    {
                        img: 'https://qn-qn-kibey-static-cdn.app-echo.com/goodboy-weixin.PNG'
                    },
                    {
                        img: 'https://avatars2.githubusercontent.com/u/15681693?s=460&v=4'
                    }
                ],
                option: {
                    img: 'https://qn-qn-kibey-static-cdn.app-echo.com/goodboy-weixin.PNG',//剪切图片地址
                    size: 1,//输出图片压缩比默认为1
                    full: false,//输出截图是否缩放
                    outputType: 'png',//输出图片格式
                    canMove: false,//是否可以拖动图片
                    fixedBox: false,//是否固定截图大小
                    original: false,//上传图片按原始比例
                    canMoveBox: true,//是否可以拖动截图框
                    autoCrop: true,//是否自成截图框
                    // 只有自动截图开启 宽度高度才生效
                    autoCropWidth: 200,//截图框宽
                    autoCropHeight: 150,//截图框高
                    centerBox: false,//截图框能否超过图片
                    high: true//是否根据dpr输出高清图片
                },
                show: true,
                imgUrl: '',
            }
        },
        components: {
            'vue-cropper': vueCropper
        },
        methods: {
            //更换图片
            changeImg() {
                this.option.img = this.lists[~~(Math.random() * this.lists.length)].img
            },
            // 自由截图
            startCrop() {
                // start
                this.crap = true
                this.$refs.cropper.startCrop()
            },
            //禁止自由截图
            stopCrop() {
                //  stop
                this.crap = false
                this.$refs.cropper.stopCrop()
            },
            //清除截图框
            clearCrop() {
                // clear
                this.$refs.cropper.clearCrop()
            },
            //重新加载图片
            refreshCrop() {
                // clear
                this.$refs.cropper.refresh()
            },
            //图片放大缩小 1 放大 | -1 缩小
            changeScale(num) {
                num = num || 1
                this.$refs.cropper.changeScale(num)
            },
            //图片向左旋转
            rotateLeft() {
                this.$refs.cropper.rotateLeft()
            },
            //图片向右旋转
            rotateRight() {
                this.$refs.cropper.rotateRight()
            },
            //转变图片格式
            finish(type) {
                // 输出
                // var test = window.open('about:blank')
                // test.document.body.innerHTML = '图片生成中..'
                //blob图片
                if (type === 'blob') {
                    this.$refs.cropper.getCropBlob((data) => {
                        var img = window.URL.createObjectURL(data)
                        this.model = true
                        this.modelSrc = img
                    })
                } else {
                    //base64格式图片
                    this.$refs.cropper.getCropData((data) => {
                        this.model = true
                        this.modelSrc = data
                    })
                }
            },
            // 实时预览函数
            realTime(data) {
                this.previews = data
                console.log(data)
            },

            finish2(type) {
                this.$refs.cropper2.getCropData((data) => {
                    this.model = true
                    this.modelSrc = data
                })
            },
            finish3(type) {
                this.$refs.cropper3.getCropData((data) => {
                    this.model = true
                    this.modelSrc = data
                })
            },
            //下载
            down(type) {
                // event.preventDefault()
                var aLink = document.createElement('a')
                aLink.download = 'demo'
                // 输出
                if (type === 'blob') {
                    this.$refs.cropper.getCropBlob((data) => {
                        this.downImg = window.URL.createObjectURL(data)
                        aLink.href = window.URL.createObjectURL(data)
                        aLink.click()
                    })
                } else {
                    this.$refs.cropper.getCropData((data) => {
                        this.downImg = data
                        aLink.href = data
                        aLink.click()
                    })
                }
            },
            //图片上传浏览器
            uploadImg(e, num) {
                //上传图片
                // this.option.img
                var file = e.target.files[0]
                if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
                    alert('图片类型必须是.gif,jpeg,jpg,png,bmp中的一种')
                    return false
                }
                var reader = new FileReader()
                reader.onload = (e) => {
                    let data
                    if (typeof e.target.result === 'object') {
                        // 把Array Buffer转化为blob 如果是base64不需要
                        data = window.URL.createObjectURL(new Blob([e.target.result]))
                    } else {
                        data = e.target.result
                    }
                    if (num === 1) {
                        this.option.img = data
                    } else if (num === 2) {
                        this.example2.img = data
                    }
                }
                // 转化为base64
                // reader.readAsDataURL(file)
                // 转化为blob
                reader.readAsArrayBuffer(file)
            },
            imgLoad(msg) {
                console.log(msg)
            },
            //截图上传OSS
            uploadImgOss() {
                this.$refs.cropper.getCropData(data => {
                    //设置图片名称
                    let name = Math.floor(Math.random()*1000000)
                    //将显示图片地址情况,防止重复上传
                    this.option.img = ''
                    //将裁剪的base64图片转换成file格式
                    let file = this.dataURLtoFile(data, name)
                    //将图片上传到OSS
                    this.uploadImage(file)
                })
            },
            //将base64转换为file格式
            dataURLtoFile(dataurl, filename) {
                //将base64转换为文件
                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 File([u8arr], filename, {type: mime})
            },
            // 将裁剪完图片上传oss
            async uploadImage(event) {
                this.imgUrl = await uploadOSS(event, 0)
                console.log(this.imgUrl)
            },
        },
        mounted: function () {
            console.log(this.$refs.cropper)
        }

css代码展示

* {
        margin: 0;
        padding: 0;
    }

    .cut {
        width: 500px;
        height: 500px;
        margin: 30px auto;
    }

    .c-item {
        max-width: 800px;
        margin: 10px auto;
        margin-top: 20px;
    }

    .content {
        margin: auto;
        max-width: 1200px;
        margin-bottom: 100px;
    }

    .test-button {
        display: flex;
        flex-wrap: wrap;
        align-content: center;
        justify-content: center;
    }

    .btn {
        display: inline-block;
        line-height: 1;
        white-space: nowrap;
        cursor: pointer;
        background: #fff;
        border: 1px solid #c0ccda;
        color: #1f2d3d;
        text-align: center;
        box-sizing: border-box;
        outline: none;
        margin: 20px 10px 0px 0px;
        padding: 9px 15px;
        font-size: 14px;
        border-radius: 4px;
        color: #fff;
        background-color: #50bfff;
        border-color: #50bfff;
        transition: all .2s ease;
        text-decoration: none;
        user-select: none;
    }

    .des {
        line-height: 30px;
    }

    code.language-html {
        padding: 10px 20px;
        margin: 10px 0px;
        display: block;
        background-color: #333;
        color: #fff;
        overflow-x: auto;
        font-family: Consolas, Monaco, Droid, Sans, Mono, Source, Code, Pro, Menlo, Lucida, Sans, Type, Writer, Ubuntu, Mono;
        border-radius: 5px;
        white-space: pre;
    }

    .show-info {
        margin-bottom: 50px;
    }

    .show-info h2 {
        line-height: 50px;
    }

    /*.title, .title:hover, .title-focus, .title:visited {
      color: black;
    }*/

    .title {
        display: block;
        text-decoration: none;
        text-align: center;
        line-height: 1.5;
        margin: 20px 0px;
        background-image: -webkit-linear-gradient(left, #3498db, #f47920 10%, #d71345 20%, #f7acbc 30%, #ffd400 40%, #3498db 50%, #f47920 60%, #d71345 70%, #f7acbc 80%, #ffd400 90%, #3498db);
        color: transparent;
        -webkit-background-clip: text;
        background-size: 200% 100%;
        animation: slide 5s infinite linear;
        font-size: 40px;
    }

    .test {
        height: 500px;
    }

    .model {
        position: fixed;
        z-index: 10;
        width: 100vw;
        height: 100vh;
        overflow: auto;
        top: 0;
        left: 0;
        background: rgba(0, 0, 0, 0.8);
    }

    .model-show {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100vw;
        height: 100vh;
    }

    .model img {
        display: block;
        margin: auto;
        max-width: 80%;
        user-select: none;
        background-position: 0px 0px, 10px 10px;
        background-size: 20px 20px;
        background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee 100%), linear-gradient(45deg, #eee 25%, white 25%, white 75%, #eee 75%, #eee 100%);
    }

    .c-item {
        display: block;
        user-select: none;
    }

    @keyframes slide {
        0% {
            background-position: 0 0;
        }
        100% {
            background-position: -100% 0;
        }
    }

oss上传

import co from 'co'

const OSSConfig = {
    uploadHost: '', //OSS上传地址
    type: 'scs',
    ossParams: {
        key: '', // key后面有用,先默认设空字符串
        region: 'oss-cn-beijing',
        success_action_status: '200', // 默认200
        accessKeyId: 'LTAIbsGio1aJI2Rp',
        accessKeySecret: '2prV8Ul9xtwzSu4yaJrGkO8zDBzoTg',
        bucket: 'jinanluke',
        dir: 'user-dir',
        host: 'http://jinanluke.oss-cn-beijing.aliyuncs.com',
    },
}

function random_string(len) {
    len = len || 32
    var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
    var maxPos = chars.length
    var pwd = ''
    for (let i = 0; i < len; i++) {
        pwd += chars.charAt(Math.floor(Math.random() * maxPos))
    }
    return pwd
}

function uploadOSS(event, type) {
    return new Promise((resolve, reject) => {
        var client = new OSS({
            region: OSSConfig.ossParams.region,
            accessKeyId: OSSConfig.ossParams.accessKeyId,
            accessKeySecret: OSSConfig.ossParams.accessKeySecret,
            bucket: OSSConfig.ossParams.bucket,
        })
        var file
        if (type == 0) {
            file = event
        } else {
            file = event.target.files[0]
        }
        let randomName = `${random_string(6)}_${file.name}`
        co(function*() {
            var result = yield client.multipartUpload(randomName, file)
            console.log(`${OSSConfig.uploadHost}/${result.name}`)
            resolve(`${OSSConfig.uploadHost}/${result.name}`)
        }).catch(function(err) {
            console.log(err)
            reject(err)
        })
    })
}

export { uploadOSS }

源码地址:https://gitee.com/WleiM/vue-cropper

你可能感兴趣的:(vue)