• vue.js3: 旋转图片并保存(vue@3.2.37)


    一,js代码:

    <template>
      <div style="background: #ffffff;" id="root" >
    
        <div style=" 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','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 = '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://www.cnblogs.com/architectforest

             对应的源码可以访问这里获取: 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
  • 相关阅读:
    许多其他C++的class样本
    cocos2d-x 3.2 它 2048 —— 第三
    hdu 4035 可能性DP 成都网络游戏
    OpenWrt 主的发展版本号trunk MT7620N 无线驱动程序bug
    [leetcode]Permutation Sequence
    Java Swing编程接口(30)---列表框:JList
    [创新工场]2014创新工场校园招聘回文字符串维修
    FFmpeg来源简单分析:结构会员管理系统-AVClass
    [Angular 2] Component relative paths
    [TypeScript] Reflection and Decorator Metadata
  • 原文地址:https://www.cnblogs.com/architectforest/p/16672148.html
Copyright © 2020-2023  润新知