vue+cropperjs实现图片剪裁,上传七牛云
来源:互联网 发布:小米4c可以4g网络吗 编辑:程序博客网 时间:2024/06/06 00:03
通过vue element UI 的upload组件,选择图片--进行图片剪裁--上传七牛云--获取图片key和hash--获取图片七牛云存储地址--上传地址到服务器。
父组件:
<template> <div class="upload-img"> <h2>上传封面<span class="mark">上传视频缩略图封面,建议上传16:9的图片,仅支持JPEG,BMP,PNG格式,图像小于2M</span></h2> <div class="select-button clearfix"> <el-upload :show-file-list="false" :auto-upload="false" :data="{token:token}" action="http://up-z2.qiniu.com/" :http-request="upload" name="file" ref="coverImg" list-type="picture-card" class="upload-plus clearfix" :on-change="handleChange" :on-preview="handlePictureCardPreview" :before-upload="handleBefore"> <i class="el-icon-plus add-img">点击添加图片</i> </el-upload> <div class="file" v-if="showCover"> <div class="file-box"> <span class="tag" :style="{backgroundColor:tagObj.color}">{{tagObj.label}}</span> <img :src="item.coverUrl" alt=""> <div class="cover-bar"> <a href="javascript:;" class="el-icon-view" @click="handleCheckView"></a> <a href="javascript:;" class="el-icon-delete2" @click="handleDelete"></a> </div> </div> </div> <cropper :panel="panel" :url="url" v-if="panel" @handleShow="handleShow" @handleGetUrl="handleGetUrl" @upload="upload"></cropper> <el-dialog v-model="dialogVisible" size="tiny"> <img width="100%" :src="dialogImageUrl" alt=""> </el-dialog> </div> </div></template><script>import url from '../urls/index'import EditVideo from '../api/service/videoEdit'import cropper from '@/components/common/cropper.vue' export default { data() { return { dialogImageUrl: '',//查看缩略图弹框的图片url dialogVisible: false,//查看缩略图弹框显示 uploadUrl:'',//上传的url fileName:"",//文件名 showCover:false,//上传缩略图成功控制是否显示 // coverUrl:"" //上传成功后的url地址 panel:false, url:'' } }, components: { cropper }, computed:{ item:{ get:function(){ return JSON.parse(window.localStorage.getItem('item')) }, set:function(value){ window.localStorage.setItem('item',JSON.stringify(value)) } }, tagObj:{ get:function(){ return this.$store.getters.GET_TAG_OBJ }, set:function(value){ this.$store.commit('UPDATE_TAG_OBJ',value) } }, token:{ get:function(){ return this.$store.getters.GET_TOKEN }, set:function(value){ return this.$store.commit('UPDATE_TOKEN',value) } } }, mounted(){ this.uploadUrl = url['Upload']; //页面加载完成 判断localStorage是否存在 try { if(this.item.coverUrl != "" && this.item.coverUrl){ this.showCover=true }else{ this.showCover=false } } catch (error) { this.showCover = false return this.file=[] this.postData.token = '' } }, methods: { handleChange:function (files) { if (!files) return; this.panel = true; this.picValue = files.raw; this.url = files.url; this.panel = true; }, //生成图片链接 getObjectURL (file) { var url = null ; if (window.createObjectURL!=undefined) { // basic url = window.createObjectURL(file) ; } else if (window.URL!=undefined) { // mozilla(firefox) url = window.URL.createObjectURL(file) ; } else if (window.webkitURL!=undefined) { // webkit or chrome url = window.webkitURL.createObjectURL(file) ; } return url ; }, //子组件修改弹出层显示和隐藏状态 handleShow:function (data) { this.panel = data }, //子组件剪裁过后的bese64图片 handleGetUrl:function (data) { this.item.coverUrl = data }, upload:function(e){ const self = this var pic = this.item.coverUrl.replace('data:image/png;base64,',''); var url = "http://up-z2.qiniu.com/putb64/-1"; //非华东空间需要根据注意事项 1 修改上传域名 var xhr = new XMLHttpRequest(); xhr.onreadystatechange=function(){ if (xhr.readyState==4){ // document.getElementById("myDiv").innerHTML=xhr.responseText; const fileName = xhr.responseText ? JSON.parse(xhr.responseText) : "" EditVideo.DownloadUrl({fileName:fileName.key,type:20}).then((data)=>{ const item=JSON.parse(window.localStorage.getItem('item')) item.coverUrl = data.fileUrl self.item.coverUrl = data.fileUrl//返回的封面url self.dialogImageUrl = data.fileUrl//查看大图的url地址 self.showCover = true //上传成功控制列表显示 window.localStorage.setItem('item',JSON.stringify(item)) }) } } xhr.open("POST", url, true); xhr.setRequestHeader("Content-Type", "application/octet-stream"); xhr.setRequestHeader("Authorization", "UpToken "+this.token); xhr.send(pic); }, //上传之前 文件类型判断 handleBefore:function(file){ const extension = file.name.split('.')[1] === 'jpeg' const extension1 = file.name.split('.')[1] === 'bmp' const extension2 = file.name.split('.')[1] === 'png' const extension3 = file.name.split('.')[1] === 'jpg' const isLt2M = file.size / 1024 / 1024 < 2 if(!extension && !extension1 && !extension2 && !extension3){ this.$notify({ type: 'error', message: '上传图片格式不正确!' }); return false } if(!isLt2M){ this.$notify({ type: 'error', message: '上传缩略图不能超过2M!' }); return false } return extension || extension1 || extension2 || extension3 }, //查看图片 handlePictureCardPreview(file) { this.dialogImageUrl = this.item.coverUrl this.dialogVisible = true; }, //查看大图 handleCheckView:function(){ this.dialogImageUrl = this.item.coverUrl this.dialogVisible = true }, //删除已上传的缩略图 handleDelete:function(){ this.file = {} this.showCover = false this.item.coverUrl = "" const item=JSON.parse(window.localStorage.getItem('item')) item.coverUrl = "" window.localStorage.setItem('item',JSON.stringify(item)) window.localStorage.removeItem('coverFile') } } }</script><style scoped> .upload-img { width: 1000px; margin: 20px auto 10px; box-shadow: 0 6px 10px 0 rgba(212, 212, 212, 0.50); background: #ffffff; } .upload-img h2 { padding: 10px; text-align: left; border-bottom: 1px solid #f4f4f4; font-size: 16px; color: #38424b; } .mark { font-size: 12px; color: #69717a; margin-left: 20px; } .select-button { text-align: left; padding: 20px 10px; } .add-img{ font-size:14px; color:#38424b; position: relative; } .add-img::before{ position: absolute; top: -25px; left: 50%; margin-left: -10px; border-radius: 50%; background: #000; color: #fff; padding: 3px; } .upload-plus{ float: left; } .file{ float: left; position: relative; } .file-box{ position: relative; line-height: 150px; float: left; margin-right: 20px; width: 235px; height: 132px; background: #f4f4f4; /* border: 1px dashed #c0ccda; */ /* border-radius: 6px; */ } .file-box img{ width: 235px; height: 132px; /* border-radius: 6px; */ } .cover-bar{ position: absolute; top: 0; left: 0; width: 235px; height: 132px; text-align: center; display: none; /* border-radius: 6px; */ background: rgba(0, 0, 0, 0.50) } .file:hover .cover-bar{ display: block; } .cover-bar a{ color: #fff; text-decoration: none; font-size: 20px; margin: 0 10px; } .tag{ position: absolute; left: 0; top: 0; z-index: 99; width: 34px; height: 17px; display: block; font-size: 14px; color: #fff; line-height: 17px; text-align: center; }</style>
子组件:
<template> <div id="cropper"> <!-- 遮罩层 --> <div class="container" v-show="panel"> <div> <img id="image" :src="url" alt="Picture"> </div> <button type="button" id="button" @click="crop">确定</button> </div> </div></template><script>import Cropper from 'cropperjs'export default { components: { }, data () { return { headerImage:'', cropper:'', croppable:false, } }, props: { picValue:String, panel:Boolean, url:String }, mounted () { //初始化这个裁剪框 var self = this; var image = document.getElementById('image'); this.cropper = new Cropper(image, { aspectRatio: 16/9, viewMode: 1, background:false, zoomable:false, ready: function () { self.croppable = true; } }); }, methods: { crop () { var croppedCanvas; var roundedCanvas; this.$emit('handleShow',false) if (!this.croppable) { return; } // Crop croppedCanvas = this.cropper.getCroppedCanvas(); // Round roundedCanvas = this.getRoundedCanvas(croppedCanvas); this.headerImage = roundedCanvas.toDataURL(); this.$emit('handleGetUrl',this.headerImage) this.$emit('upload') }, getRoundedCanvas (sourceCanvas) { var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); var width = sourceCanvas.width; var height = sourceCanvas.height; canvas.width = width; canvas.height = height; context.imageSmoothingEnabled = true; context.drawImage(sourceCanvas, 0, 0, width, height); context.globalCompositeOperation = 'destination-in'; context.beginPath(); // context.arc(width / 2, height / 2, Math.min(width, height) / 2, 0, 2 * Math.PI, true); context.fill(); return canvas; } }}</script><style>*{ margin: 0; padding: 0;}#cropper #button { position: absolute; right: 10px; top: 10px; width: 80px; color: #fff; height: 40px; border: none; border-radius: 5px; background: #24a4ff;}#cropper .show { width: 100px; height: 100px; overflow: hidden; position: relative; /* border-radius: 50%; */ border: 1px solid #d5d5d5;}#cropper .picture { width: 100%; height: 100%; overflow: hidden; background-position: center center; background-repeat: no-repeat; background-size: cover;}#cropper .container { z-index: 99; position: fixed; padding-top: 60px; left: 0; top: 0; right: 0; bottom: 0; background:rgba(0,0,0,1);}#cropper #image { max-width: 100%;}.cropper-view-box,.cropper-face { /* border-radius: 50%; */}/*! * Cropper.js v1.0.0-rc * https://github.com/fengyuanchen/cropperjs * * Copyright (c) 2017 Fengyuan Chen * Released under the MIT license * * Date: 2017-03-25T12:02:21.062Z */.cropper-container { font-size: 0; line-height: 0; position: relative; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; direction: ltr; -ms-touch-action: none; touch-action: none}.cropper-container img { /* Avoid margin top issue (Occur only when margin-top <= -height) */ display: block; min-width: 0 !important; max-width: none !important; min-height: 0 !important; max-height: none !important; width: 100%; height: 100%; image-orientation: 0deg}.cropper-wrap-box,.cropper-canvas,.cropper-drag-box,.cropper-crop-box,.cropper-modal { position: absolute; top: 0; right: 0; bottom: 0; left: 0;}.cropper-wrap-box { overflow: hidden;}.cropper-drag-box { opacity: 0; background-color: #fff;}.cropper-modal { opacity: .5; background-color: #000;}.cropper-view-box { display: block; overflow: hidden; width: 100%; height: 100%; outline: 1px solid #39f; outline-color: rgba(51, 153, 255, 0.75);}.cropper-dashed { position: absolute; display: block; opacity: .5; border: 0 dashed #eee}.cropper-dashed.dashed-h { top: 33.33333%; left: 0; width: 100%; height: 33.33333%; border-top-width: 1px; border-bottom-width: 1px}.cropper-dashed.dashed-v { top: 0; left: 33.33333%; width: 33.33333%; height: 100%; border-right-width: 1px; border-left-width: 1px}.cropper-center { position: absolute; top: 50%; left: 50%; display: block; width: 0; height: 0; opacity: .75}.cropper-center:before, .cropper-center:after { position: absolute; display: block; content: ' '; background-color: #eee}.cropper-center:before { top: 0; left: -3px; width: 7px; height: 1px}.cropper-center:after { top: -3px; left: 0; width: 1px; height: 7px}.cropper-face,.cropper-line,.cropper-point { position: absolute; display: block; width: 100%; height: 100%; opacity: .1;}.cropper-face { top: 0; left: 0; background-color: #fff;}.cropper-line { background-color: #39f}.cropper-line.line-e { top: 0; right: -3px; width: 5px; cursor: e-resize}.cropper-line.line-n { top: -3px; left: 0; height: 5px; cursor: n-resize}.cropper-line.line-w { top: 0; left: -3px; width: 5px; cursor: w-resize}.cropper-line.line-s { bottom: -3px; left: 0; height: 5px; cursor: s-resize}.cropper-point { width: 5px; height: 5px; opacity: .75; background-color: #39f}.cropper-point.point-e { top: 50%; right: -3px; margin-top: -3px; cursor: e-resize}.cropper-point.point-n { top: -3px; left: 50%; margin-left: -3px; cursor: n-resize}.cropper-point.point-w { top: 50%; left: -3px; margin-top: -3px; cursor: w-resize}.cropper-point.point-s { bottom: -3px; left: 50%; margin-left: -3px; cursor: s-resize}.cropper-point.point-ne { top: -3px; right: -3px; cursor: ne-resize}.cropper-point.point-nw { top: -3px; left: -3px; cursor: nw-resize}.cropper-point.point-sw { bottom: -3px; left: -3px; cursor: sw-resize}.cropper-point.point-se { right: -3px; bottom: -3px; width: 20px; height: 20px; cursor: se-resize; opacity: 1}@media (min-width: 768px) { .cropper-point.point-se { width: 15px; height: 15px }}@media (min-width: 992px) { .cropper-point.point-se { width: 10px; height: 10px }}@media (min-width: 1200px) { .cropper-point.point-se { width: 5px; height: 5px; opacity: .75 }}.cropper-point.point-se:before { position: absolute; right: -50%; bottom: -50%; display: block; width: 200%; height: 200%; content: ' '; opacity: 0; background-color: #39f}.cropper-invisible { opacity: 0;}.cropper-bg { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');}.cropper-hide { position: absolute; display: block; width: 0; height: 0;}.cropper-hidden { display: none !important;}.cropper-move { cursor: move;}.cropper-crop { cursor: crosshair;}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point { cursor: not-allowed;}</style>
阅读全文
0 0
- vue+cropperjs实现图片剪裁,上传七牛云
- 上传 图片 剪裁
- 图片剪裁并上传
- 图片上传剪裁
- 图片剪裁并上传
- canvas图片上传剪裁
- cropperjs在.vue中的使用
- 使用Jcrop实现图片上传、剪裁和保存(ASP.NET)
- 利用javascript剪裁图片(也许CSDN也是如此实现图像上传剪裁)
- bootstrap图片剪裁预览上传
- 图片剪裁并预览上传
- vue中实现图片丶文件上传
- Android上传头像,图片剪裁,压缩图片
- Android上传头像,图片剪裁,压缩图片
- Android上传头像,图片剪裁,压缩图片
- Android图片剪裁的实现
- 使用Cropper进行图片剪裁上传
- ASP.NET z中使用crop实现图片上传、剪裁和保存
- ScrollView中滑动控件
- 程序员如何转型项目经理?
- jQuery,JQ显示与隐藏
- Python之路【第十六篇】:Django【基础篇】
- Python输出当前时间
- vue+cropperjs实现图片剪裁,上传七牛云
- OSPF邻接建立状态--Smallbaal的博客
- 安装percona 5.7
- 史上最强Java学习路线(详解)
- opc-ua技术资料网站汇总
- MapReduce运行全流程
- 投区块链?听听当下硅谷最火的四条投资军规
- go语言-defer关键字
- 微信页面禁止长按复制(input输入框可正常输入)