base64图片旋转后得到一个base64图片

base64图片旋转后得到一个base64图片

1.vue-esign签名插件

2.生成图片的图片的旋转

//第一个base64地址, 第二个顺时针角度, 第三个回调函数
	this.rotateBase64Img(src, edg, data => {
		console.log("旋转后的base64", data);
	}) 
 // 旋转图片
      rotateBase64Img(src, edg, callback) {
        var canvas = document.createElement('canvas')
        var ctx = canvas.getContext('2d')

        var imgW // 图片宽度
        var imgH // 图片高度
        var size // canvas初始大小

        if (edg % 90 !== 0) {
          console.error('旋转角度必须是90的倍数!')
          return '旋转角度必须是90的倍数!'
        }
        edg < 0 && (edg = (edg % 360) + 360)
        const quadrant = (edg / 90) % 4 // 旋转象限
        const cutCoor = { sx: 0, sy: 0, ex: 0, ey: 0 } // 裁剪坐标

        var image = new Image()
        image.crossOrigin = 'Anonymous'
        image.src = src

        image.onload = () => {
          imgW = image.width
          imgH = image.height
          size = imgW > imgH ? imgW : imgH

          canvas.width = size * 2
          canvas.height = size * 2
          switch (quadrant) {
            case 0:
              cutCoor.sx = size
              cutCoor.sy = size
              cutCoor.ex = size + imgW
              cutCoor.ey = size + imgH
              break
            case 1:
              cutCoor.sx = size - imgH
              cutCoor.sy = size
              cutCoor.ex = size
              cutCoor.ey = size + imgW
              break
            case 2:
              cutCoor.sx = size - imgW
              cutCoor.sy = size - imgH
              cutCoor.ex = size
              cutCoor.ey = size
              break
            case 3:
              cutCoor.sx = size
              cutCoor.sy = size - imgW
              cutCoor.ex = size + imgH
              cutCoor.ey = size + imgW
              break
          }

          ctx.translate(size, size)
          ctx.rotate((edg * Math.PI) / 180)
          ctx.drawImage(image, 0, 0)

          var imgData = ctx.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey)

          if (quadrant % 2 === 0) {
            canvas.width = imgW
            canvas.height = imgH
          } else {
            canvas.width = imgH
            canvas.height = imgW
          }

          ctx.putImageData(imgData, 0, 0)
          // callback(dataURLtoFileBlob(src))
          callback(canvas.toDataURL())
          // callback(canvas.toDataURL())
        }
      },

3.将 base64的图片 转换为 file 对象

      // 附:base64转化成图片
      base64ImgtoFile (dataurl, fileName = "file") {
        const arr = dataurl.split(",");
        const mime = arr[0].match(/:(.*?);/)[1];
        const suffix = mime.split("/")[1];
        const bstr = atob(arr[1]);
        let n = bstr.length;
        var u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n);
        }
        return new File([u8arr], `${fileName}.${suffix}`, { type: mime });
      },

============================================================================

实例代码

<template>
    <div>
      <div class="NavBar">
        <bn-navBar title="电子签名" :leftArrow="false"></bn-navBar>
      </div>
  
      <div>
        <div class="SignPlace">
          <vue-esign
            ref="esign"
            class="esign-box"
            :width="windowWidth"
            :height="750"
            :isCrop="isCrop"
            :lineWidth="lineWidth"
            :lineColor="lineColor"
          />
  
          <!-- 写好的签字会放在这个图片里 -->
          <img :src="imgSrc" width="400" :height="windowHeight" v-if="false" />
        </div>
        <div class="SignTips" id="main">
          <span id="TipSpan">请在上方空白处书写您的名字</span>
          <van-button type="info" @click="handleGenerate">提交签字</van-button>
          <van-button
            plain
            type="info"
            style="background-color: transparent"
            @click="handleReset"
            >清除重写</van-button
          >
        </div>
      </div>
    </div>
  </template>
  
  <script>
  const environment = process.env.VUE_APP_ENV || 'production'
  
  import { Toast } from "vant";
  import axios from "axios";
  import { setMoSignature, getCosInfo } from "../../api/register";
  
  export default {
    data () {
      return {
        lineWidth: 5,
        lineColor: "black",
        resultImg: "",
        isCrop: false,
        imgSrc: "",
        signImage: null,
        windowWidth: document.documentElement.clientWidth, //获取屏幕宽度
        windowHeight: window.innerHeight, //获取屏幕高度
      };
    },
    created () {
      console.log(
        "document.documentElement.clientHeight",
        document.documentElement.clientHeight
      );
      console.log("this.$route.params", this.$route.params);
    },
  
    methods: {
      handleReset () {
        this.$refs.esign.reset();
      },
      // 生成签名的base64图片 提交
      handleGenerate () {
        this.$refs.esign.generate()
          .then((res) => {
            // 1.先将签名旋转 res-旋转前base64,  data-旋转后base64
            this.rotateBase64Img(res, 270, data => {
              // 打印旋转后的图片base64
              console.log('data', data);

              // 2.将base64文件转为File文件-图片
              this.imgSrc = res            
              const file = this.base64ImgtoFile(data);
              console.log('res', res);
              // 3.再将签名提交到
              const that = this;
              if (file) {
                console.log("file", file);
                this.getCosInfoFn(file);
              }
            })

          })
          .catch((err) => {
            const errorMessage = "提交签名时出错,因为还未进行签字。";
            Toast("请设置签名");
            console.error(errorMessage);
            console.log("画布没有签字时会执行这里 Not Signned");
          });
      },
      // 附:base64转化成图片
      base64ImgtoFile (dataurl, fileName = "file") {
        const arr = dataurl.split(",");
        const mime = arr[0].match(/:(.*?);/)[1];
        const suffix = mime.split("/")[1];
        const bstr = atob(arr[1]);
        let n = bstr.length;
        var u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n);
        }
        return new File([u8arr], `${fileName}.${suffix}`, { type: mime });
      },

      // 提交
      async submitNextFn (data) {
        console.log('提交啦··········!,this.signImage', this.signImage)
        const res = await setMoSignature({
          signatureImgUrl: this.signImage,
          signatureId: Number(this.$route.query.signatureId)
        });
        console.log('签名已提交1a', res);
        if (res.code == 200) {
          this.$router.push('/signingSuccess')
        } else {
          Toast(res.message);
        }
      },
  
      // 获取cos签名
      async getCosInfoFn (file, data) {
        const res = await getCosInfo({
          scene: "product_drug",
          suffix: file.name.split(".").pop().toLowerCase(),
          size: file.size,
        });
        console.log("获取cos签名", res);
        if (res.status === 200) {
          var xhr = new XMLHttpRequest();
          xhr.open("PUT", res.data.url, true);
          xhr.onload = function (e) { };
          xhr.onerror = function (e) {
            that.$message({
              message: "上传错误",
              type: "error",
            });
          };
          xhr.send(file);
          this.signImage = res.data.returnUrl;
          this.submitNextFn();
          console.log("获取cos签名url", res.data.returnUrl);
        }
      },

 // 旋转图片
      rotateBase64Img(src, edg, callback) {
        var canvas = document.createElement('canvas')
        var ctx = canvas.getContext('2d')

        var imgW // 图片宽度
        var imgH // 图片高度
        var size // canvas初始大小

        if (edg % 90 !== 0) {
          console.error('旋转角度必须是90的倍数!')
          return '旋转角度必须是90的倍数!'
        }
        edg < 0 && (edg = (edg % 360) + 360)
        const quadrant = (edg / 90) % 4 // 旋转象限
        const cutCoor = { sx: 0, sy: 0, ex: 0, ey: 0 } // 裁剪坐标

        var image = new Image()
        image.crossOrigin = 'Anonymous'
        image.src = src

        image.onload = () => {
          imgW = image.width
          imgH = image.height
          size = imgW > imgH ? imgW : imgH

          canvas.width = size * 2
          canvas.height = size * 2
          switch (quadrant) {
            case 0:
              cutCoor.sx = size
              cutCoor.sy = size
              cutCoor.ex = size + imgW
              cutCoor.ey = size + imgH
              break
            case 1:
              cutCoor.sx = size - imgH
              cutCoor.sy = size
              cutCoor.ex = size
              cutCoor.ey = size + imgW
              break
            case 2:
              cutCoor.sx = size - imgW
              cutCoor.sy = size - imgH
              cutCoor.ex = size
              cutCoor.ey = size
              break
            case 3:
              cutCoor.sx = size
              cutCoor.sy = size - imgW
              cutCoor.ex = size + imgH
              cutCoor.ey = size + imgW
              break
          }

          ctx.translate(size, size)
          ctx.rotate((edg * Math.PI) / 180)
          ctx.drawImage(image, 0, 0)

          var imgData = ctx.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey)

          if (quadrant % 2 === 0) {
            canvas.width = imgW
            canvas.height = imgH
          } else {
            canvas.width = imgH
            canvas.height = imgW
          }

          ctx.putImageData(imgData, 0, 0)
          // callback(dataURLtoFileBlob(src))
          callback(canvas.toDataURL())
          // callback(canvas.toDataURL())
        }
      },
    },

    // 兼容屏幕
    watch: {
      windowHeight (val) {
        let that = this;
        console.log("实时屏幕高度:", val, that.windowHeight);
      },
      windowWidth (val) {
        let that = this;
        console.log("实时屏幕宽度:", val, that.windowHeight);
      },
    },
  };
  </script>
  
  <style scoped lang="less">
  .body {
    position: relative;
    width: 100%;
    height: 100%;
  }
  /deep/.van-nav-bar__title {
    font-weight: 550;
  }
  .SignTips {
    width: 10%;
    height: 22%;
  }
  #TipSpan {
    font-size: 4vw;
    line-height: 22vw;
    margin-left: 20vw;
  }
  .van-button {
    float: right;
    top: 6vw;
    margin-right: 4vw;
    border-radius: 12px;
    height: 10vw;
    width: 30vw;
  }
  .SignPlace {
    position: absolute;
    width: 100%;
    height: 100%;
  }
  
  #main {
    position: fixed;
    padding: 0;
    margin: 0;
    overflow: hidden;
  }
  
  #main {
    position: absolute;
    width: 100vh;
    height: 20vw;
    top: 0;
    left: 20vw;
    -webkit-transform: rotate(90deg);
    -moz-transform: rotate(90deg);
    -ms-transform: rotate(90deg);
    transform: rotate(90deg);
    transform-origin: 0% 0%;
  }
  
  @media screen and (orientation: landscape) {
    #main {
      position: absolute;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
    }
  }
  html,body{
    width:100%;
    height: 100%;
  }
  .esign-box {
    width: 100%;
    height: 100%;
  }
  </style>
  
  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值