头像裁剪压缩上传流程:
点击头像–判断是否为IOS端–若是–A,否则–B
A:选择图片 –C
B:弹框供用户选择从相册选择或者调用相机拍照–选择图片–C
C:出现cropper裁剪框,裁剪框位于图片上方,用户可以拖动或者放大缩小裁剪框–用户手动调整后–代码执行压缩并上传
1.引入vueCropper组件
地址:https://www.npmjs.com/package/vue-cropper/v/0.4.7
npm install vue-cropper --save-dev <script> import { VueCropper } from 'vue-cropper' export default { name: 'UserProfile', components: { VueCropper }, } </script>
使用vue-cropper组件
<!-- 剪裁图片组件 --> <van-popup class="bg-tran" v-model="showCropper" closeable position="top" :style="{ height: '100%' }" > <div class="flex-column-center height100"> <vueCropper ref="cropper" :img="option.img" :outputSize="option.outputSize" :outputType="option.outputType" :info="option.info" :full="option.full" :autoCropWidth="option.autoCropWidth" :autoCropHeight="option.autoCropHeight" :canMove="option.canMove" :canMoveBox="option.canMoveBox" :original="option.original" :autoCrop="option.autoCrop" :fixed="option.fixed" :fixedNumber="option.fixedNumber" :centerBox="option.centerBox" :infoTrue="option.infoTrue" :fixedBox="option.fixedBox" :high="option.high" :mode="option.mode" ></vueCropper> <van-col span="24" class="font14 col-white"> <van-col span="8" class="p-2"><span @click="cancelCropper">取消</span></van-col> <van-col span="8" class="p-2 text-center"><span @click="rotateImage" class="font18"><van-icon name="replay" /></span></van-col> <van-col span="8" class="p-2 text-right"><span @click="getCropBlob">确定</span></van-col> </van-col> </div> </van-popup>
vue-cropper配置:
<script> export default { data() { return { option: { img: '', outputSize: 0.8, info: false, // 裁剪框的大小信息 outputType: 'jpeg', // 裁剪生成图片的格式 canScale: false, // 图片是否允许滚轮缩放 autoCrop: true, // 是否默认生成截图框 autoCropWidth: window.innerWidth - 100 + 'px', // 默认生成截图框宽度 autoCropHeight: window.innerWidth - 100 + 'px', // 默认生成截图框高度 high: true, // 是否按照设备的dpr 输出等比例图片 fixedBox: true, // 固定截图框大小 不允许改变 fixed: true, // 是否开启截图框宽高固定比例 fixedNumber: [1, 1], // 截图框的宽高比例 full: true, // 是否输出原图比例的截图 canMoveBox: false, // 截图框能否拖动 original: false, // 上传图片按照原始比例渲染 centerBox: false, // 截图框是否被限制在图片里面 infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高 mode: '100% auto' // 图片默认渲染方式 } } } } </script>
2.点击头像选择文件,裁剪压缩并上传
这里需要判断是否为苹果手机;
苹果手机点击上传头像会默认弹框显示拍照还是从文件中选择,安卓手机点击上传头像则默认从文件中选择;
这里判断如果是安卓手机则显示我们自定义的弹框供用户选择是拍照还是从文件中选择
<!--点击上传头像 --> <van-cell-group> <van-cell title="头像" is-link @click="checkIsIos" /><!-- 检测是否为苹果手机 --> <img v-if="fromWX" :src="wxImgUrl"> <!-- 默认显示微信头像(带http的绝对链接) --> <img v-else :src="headImgUrl"> <input type="file" name="fileIOS" @change="changeImgIOS" accept="image/*" ref="inputFileRefIOS" style="display:none;" /> </van-cell> </van-cell-group> <!--安卓上传头像弹框,需要注意的是调用相机时,type="file" name="file" capture="camera" 必须写正确,否则调用相机不成功 --> <van-popup v-model="uploadModal" position="bottom"> <div> <div @click="openFile">从相册中选择</div> <input type="file" name="file" @change="changeImg" accept="image/*" ref="inputFileRef" style="display:none;" /> <div @click="openFile">拍照</div> <input type="file" name="file" @change="changeImg" accept="image/*" ref="inputFileRef" capture="camera" style="display:none;" /> <div @click="uploadModal = false">取消</div> </div> </van-popup>
methods:{ checkIsIoS(){//点击头像调用的方法 if(!this.isIOS){//非IOS则显示自定义弹框 this.uploadModal = true this.isCamera = true }else{ this.$refs.inputFIleRefIOS.click()//IOS选择文件,触发changeImgIOS方法 } }, //IOS选择文件 changeImgIOS(){ let file = this.$refs.inputFIleRefIOS.file[0] this.showCropper = true//显示裁剪框 this.imageFileName = file.name //保存上传的文件名,方便后续用到 this.imageToBase64(file)//图片压缩并转化为base64,否则cropper组件显示不出要裁剪的图片 }, //安卓选择文件,从相册中选择 openFile(){ this.$refs.inputFIleRef.click() }, //安卓选择文件,调用相机 openFile(){ this.isCamera = true this.$refs.inputFIleRef.click() }, changeImg(){ this.uploadModal = false let file = null if(this.isCamera){ file = this.$refs.inputFIleRefCamera.files[0]//相机拍照的 }else{ file = this.$refs.inputFIleRef.files[0]//相册选择的 } this.showCropper = true this.imageFileName = file.name this.imageToBase64(file) }, imageToBase64(file){ this.option.img = ''//清空上一次裁剪的图片 let reader = new FileReader() reader.readAsDataURL(file) reader.onload = () =>{ if(file.size>(1*1024*1024)){//大于 1M 的图片压缩 let scaleSize = 0.9//定义压缩的比例(程度) let image = new Image() image.src = reader.result; image.onload = () =>{ if(file.size>(1*1024*1024) && file.size<(2*1024*1024+1)){//1-2M scaleSize = 0.9 } if(file.size>(2*1024*1024) && file.size<(3*1024*1024+1)){//2-3M scaleSize = 0.9 } if(file.size>(3*1024*1024) && file.size<(4*1024*1024+1)){//3-4M scaleSize = 0.9 } if(file.size>(4*1024*1024)){//4M+ scaleSize = 0.9 } let img64 = this.compress(image,scaleSize) this.option.img = img64 } }else{ this.option.img = reader.result } } reader.onerror = (rrror) =>{ console.log(error) } }, compress(img,ratio){//图片压缩并转化为base64返回 let canvas,ctx,img64; let width = img.width*0.6//改变上传的图片像素,缩放至原来的0.6 let height = img.height*0.6 canvas = document.createElement('canvas') canvas.width = width canvas.height = height ctx = canvas.getContext('2d') ctx.drawImage(img,0,0,width,height) img64 = canvas.toDataURL('image/jpeg',ratio)//参考 https://www.runoob.com/jsref/met-canvas-drawimage.html return img64 }, //绑定在cropper组件上的方法,确认裁剪并上传图片到后台 getCropBlob(){ let toast = Toast.loading({ duration:0, forbidClick:true, message:'加载中' }) let formData = new FormData() this.$refs.cropper.getCropBlob(async (data) =>{ formData.append('custId',this.custId) formData.append('multiReq',data,this.imageFileName) let rs = await axios({ method:'post', url:cfg.baseURL.XXX + '', data:formData, headers:{ openId:sessionStorage.getItem('openId') } }) if(rs.data.code=='200'){ Toast.clear() Toase.success('上传成功') }else{ Toast.clear() Toase.fail('修改异常') } this.showCropper = false //隐藏裁剪遮罩 this.isCamera = false }) }, //旋转图片 rotateImage(){ this.$refs.cropper.rotateImage() }, //取消截图上传头像 cancelCropper(){ this.showCropper = false; this.isCamera = false } }, mounted(){ let u = navigator.userAgent this.isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) },
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/159673.html