vue.js3: 旋转图片并保存(vue@3.2.37)
一,js代码:
<template> <div style="background: #ffffff;" id="root" > <div style="width: 700px;margin: auto;"> <div><input type="file" accept="image/*" @change="open" /></div> <div><button @click="rotate(-1)">逆时针旋转90度</button> <button @click="rotate(1)">顺时针旋转90度</button> <button @click="reset">重置</button></div> <div id="wrapper" :style="{marginTop:'10px',background:'lightgray',position: 'relative',lineHeight:lineLength+'px',width:'700px',height:lineLength+'px',overflow: 'hidden'}" > <img id="img" :src="imgSrc" style="position: absolute; transform: rotateZ(0deg);" /> </div> <div><button style="margin-top: 10px;" id="saveBtn" @click="save">保存</button></div> </div> </div> </template> <script> //computed, ,watch import {ref} from "vue"; export default { name: "RotateImg", setup() { //旋转的度数 let roDeg = 0; //旋转 const rotate = (deg) => { if (deg == -1) { roDeg = roDeg - 90; } if (deg == 1) { roDeg = roDeg + 90; } let box = document.getElementById('img'); box.style.transform = 'rotateZ('+roDeg+'deg)'; box.style.transitionDuration = '500ms'; box.style.transitionTimingFunction = 'linear'; } //重置 const reset = () => { roDeg = 0; let box = document.getElementById('img'); box.style.transform = 'rotateZ('+roDeg+'deg)'; box.style.transitionDuration = '0ms'; box.style.transitionTimingFunction = 'linear'; }; //图片的src const imgSrc = ref(""); //图片的原宽高 const imgWidth = ref(0); const imgHeight = ref(0); //读取图片的信息 const open = (e) => { let file = e.target.files[0]; let reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () =>{ //清除原来记录的度数,清除原来的样式 reset(); //显示图片 imgSrc.value = reader.result; //得到宽高 let img = new Image(); img.src= reader.result; img.onload = () => { //保存原始宽高 imgWidth.value = img.width; imgHeight.value = img.height; //处理图片的显示宽度/高度 let imgStyle = document.getElementById('img').getAttributeNode('style'); let wrapper = document.getElementById('wrapper'); if (img.width >= img.height) { let iHeight = (500*img.height) / img.width; let itop = (500-iHeight)/2; imgStyle.value = 'width:500px;left:100px;top:'+itop+'px;position:absolute;display: block;'; wrapper.style.height = "500px"; } else { let iWidth = (500*img.width) / img.height; let iLeft = (700 - iWidth) / 2; imgStyle.value = 'height:500px;top:50px;left:'+iLeft+'px;position:absolute;display: block;'; wrapper.style.height = "600px"; } } } } //保存图片 const save = () => { let img = document.getElementById('img') //创建canvas const canvas = document.createElement('canvas') if (canvas.getContext) { let context = canvas.getContext('2d'); let degree = getDegree(roDeg); //旋转context并画图 if (degree === 0) { canvas.width = imgWidth.value; canvas.height = imgHeight.value; context.rotate(0 * Math.PI / 180); context.drawImage(img, 0, 0); } else if (degree === 90) { canvas.width = imgHeight.value; canvas.height = imgWidth.value; context.rotate(90 * Math.PI / 180); context.drawImage(img, 0, -imgHeight.value); } else if (degree === 180) { canvas.width = imgWidth.value; canvas.height = imgHeight.value; context.rotate(180 * Math.PI / 180); context.drawImage(img, -imgWidth.value, -imgHeight.value); } else if (degree === 270) { canvas.width = imgHeight.value; canvas.height = imgWidth.value; context.rotate(270 * Math.PI / 180); context.drawImage(img, -imgWidth.value, 0); } downJpgByCanvas(canvas); } } //得到计算后的旋转度数 const getDegree = (deg) => { let abs = Math.abs(deg); console.log('abs:'+abs); let yvshu = abs % 360; console.log('yvshu:'+yvshu); if (deg >= 0) { return yvshu; } else { if (yvshu == 0) { return 0; } else { return 360+(0-yvshu); } } } //下载图片 const downJpgByCanvas = (canvas) => { var oA = document.createElement("a"); let time = timeFormat(); oA.download = "img_"+time+'.jpg';// 设置下载的文件名,默认是'下载' oA.href = canvas.toDataURL("image/jpeg"); document.body.appendChild(oA); oA.click(); oA.remove(); // 下载之后把创建的元素删除 } //补0 const add0 = (m) => { return m<10?'0'+m:m } //格式化时间 const timeFormat = ()=>{ var time = new Date(); var y = time.getFullYear(); var m = time.getMonth()+1; var d = time.getDate(); var h = time.getHours(); var mm = time.getMinutes(); var s = time.getSeconds(); let res = y+add0(m)+add0(d)+add0(h)+add0(mm)+add0(s); return res; } return { rotate, reset, open, save, imgSrc, } } } </script> <style scoped> </style>
说明:刘宏缔的架构森林是一个专注架构的博客,
网站:https://blog.imgtouch.com
本文: https://blog.imgtouch.com/index.php/2023/06/02/vue-js3-xuan-zhuan-tu-pian-bing-bao-cun-vue-3-2-37/
对应的源码可以访问这里获取: https://github.com/liuhongdi/
或: https://gitee.com/liuhongdi
说明:作者:刘宏缔 邮箱: 371125307@qq.com
二,测试效果
旋转后保存:
三,查看vue框架的版本:
liuhongdi@lhdpc:/data/vue/pdf/image2pdf$ npm list vue image2pdf@0.1.0 /data/vue/pdf/image2pdf ├─┬ @vue/cli-plugin-babel@5.0.8 │ └─┬ @vue/babel-preset-app@5.0.8 │ ├─┬ @vue/babel-preset-jsx@1.3.0 │ │ └── vue@3.2.37 deduped invalid: "2.x" from node_modules/@vue/babel-preset-jsx │ └── vue@3.2.37 deduped └─┬ vue@3.2.37 └─┬ @vue/server-renderer@3.2.37 └── vue@3.2.37 deduped