bug:后台返的网络图片路径保存不下来,返回base64格式即可

在这里插入图片描述

保存图片的方式

import html2canvas from “html2canvas”;

 // 点击上传,获取图片url
      toImg() {
        let that = this
        html2canvas(document.querySelector('.leftimg')).then(canvas => {
          let imgUrl = canvas.toDataURL('image/png');
          console.log(imgUrl);
          that.dataURL = imgUrl;   //base64格式
        }).catch(error => {})
      },

整个制作海报的代码(elementUI,vant上传图片,vue.js)

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <!-- 引入样式 -->
  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" />
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vant@2.2/lib/index.css" />
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vant@2.2/lib/vant.min.js"></script>
</head>
<style>
  * {
    box-sizing: border-box;
    padding: 0;
    margin: 0;
  }

  #app {
    width: 100%;
    height: 100vh;
    display: flex;
    justify-content: space-between;
  }

  .left {
    background-color: #222D32;
    width: 580px;
    height: 100vh;
    position: relative;
  }

  .leftimg {
    width: 100%;
    height: 100%;
  }

  .left .bgimg {
    width: 475px;
    height: 808px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
  }

  .right {
    flex: 1;
    height: 100vh;
    position: relative;
    /* padding: 70px; */
  }

  /* 上传图片 */

  .van-uploader__upload {
    width: 120px;
    height: 120px;
  }

  .van-uploader__preview-image {
    width: 120px;
    height: 120px;
  }

  .name {
    position: absolute;
    top: 100px;
    left: 100px;
  }

  .Tel {
    position: absolute;
    top: 150px;
    left: 100px;
  }

  .site {
    position: absolute;
    top: 200px;
    left: 100px;
  }

  .date {
    position: absolute;
    top: 250px;
    left: 100px;
  }

  .minTu {
    margin-top: 50px;
  }

  .mintou {
    margin-top: 50px;
  }

  .erweima {
    width: 120px;
    height: 120px;
    position: absolute;
    left: 230px;
    top: 600px;
  }

  .tou {
    width: 100px;
    height: 100px;
    position: absolute;
    left: 100px;
    top: 100px;
    border-radius: 50px;
  }

  .minTu span {
    display: block;
    height: 50px;
    float: left;
    margin-right: 10px;
  }

  .minTu img {
    width: 50px;
    height: 50px;
  }

  .mintou img {
    width: 50px;
    height: 50px;
  }

  .avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }

  .avatar-uploader .el-upload:hover {
    border-color: #409eff;
  }

  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
  }

  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }

  /* .ipt {
    position: absolute;
    left: 165px;
    bottom: 27px;
  } */

  .el-input-number--mini {
    margin: 20px 20px 0 0;
  }

  .input {
    margin: 40px 0 0;
  }

  .btn {
    position: absolute;
    bottom: 100px;
    left: 48%;
  }
</style>

<body>
  <div id="app">
    <div class="left">
      <!-- <div class="canvas" ref="canvas"> -->
      <div class="leftimg">
        <img :src="bgimg[0].content" alt="" class="bgimg" v-if="bgimg[0]" />
        <img :src="img1[0].content" alt="" class="tou" v-if="img1[0]" />
        <img :src="img2[0].content" alt="" v-if="img2[0]" class="erweima" />
        <pre class="name">{{ mingzi }}</pre>
        <pre class="Tel">{{ dianhua }}</pre>
        <pre class="site">{{ dizhi }}</pre>
        <pre class="date">{{ riqi }}</pre>
      </div>

      <!-- </div> -->
    </div>
    <div class="right">
      <!-- tab切换 -->
      <el-menu :default-active="activeIndex2" class="el-menu-demo" mode="horizontal" @select="handleSelect"
        background-color="#18BC9C" text-color="#fff" active-text-color="#ffd04b">
        <el-menu-item index="1">背景图片</el-menu-item>
        <el-submenu index="2">
          <template slot="title">头像/二维码</template>
          <el-menu-item index="21">头像</el-menu-item>
          <el-menu-item index="22">二维码</el-menu-item>
          <!-- <el-menu-item index="23">其他</el-menu-item> -->
        </el-submenu>
        <el-menu-item index="3">添加文本</el-menu-item>
      </el-menu>

      <!-- 背景图 -->
      <div v-if="tab==1" style="padding: 20px;">
        <div style="color:#333;margin-bottom:10px;">添加图像</div>
        <van-uploader v-model="bgimg" multiple :max-count="1"></van-uploader>

        <div class="ipt">
          <el-tooltip class="item" effect="dark" content="宽度" placement="top-start">
            <el-button>上左</el-button>
            <el-input-number size="mini" v-model="bgwd" class="bgwd"></el-input-number>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="高度" placement="top-start">
            <el-button>上左</el-button>
            <el-input-number size="mini" v-model="bghi" class="bgwd"></el-input-number>
          </el-tooltip>
        </div>
        <img :src="dataURL" alt="" v-if="dataURL">
      </div>

      <!-- 图像 -->
      <div v-if="tab==21" style="padding: 20px;">
        <div style="color:#333;margin-bottom:10px;">添加头像</div>
        <van-uploader v-model="img1" multiple :max-count="1"></van-uploader>

        <div class="ipt">
          <el-tooltip class="item" effect="dark" content="宽度" placement="top-start">
            <el-button>上左</el-button>
            <el-input-number size="mini" v-model="touw" class="touw"></el-input-number>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="高度" placement="top-start">
            <el-button>上左</el-button>
            <el-input-number size="mini" v-model="touh" class="touh"></el-input-number>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="横坐标" placement="top-start">
            <el-button>上左</el-button>
            <el-input-number size="mini" v-model="toux" class="toux"></el-input-number>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="纵坐标" placement="top-start">
            <el-button>上左</el-button>
            <el-input-number size="mini" v-model="touy" class="touy"></el-input-number>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="圆角弧度" placement="top-start">
            <el-button>上左</el-button>
            <el-input-number size="mini" v-model="tour" class="touy"></el-input-number>
          </el-tooltip>
        </div>
      </div>

      <!-- 二维码 -->
      <div v-if="tab==22" style="padding: 20px;">
        <div style="color:#333;margin-bottom:10px;">添加二维码</div>
        <van-uploader v-model="img2" multiple :max-count="1"></van-uploader>

        <div class="ipt">
          <el-tooltip class="item" effect="dark" content="宽度" placement="top-start">
            <el-button>上左</el-button>
            <el-input-number size="mini" v-model="imgw" class="imgw"></el-input-number>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="高度" placement="top-start">
            <el-button>上左</el-button>
            <el-input-number size="mini" v-model="imgh" class="imgh"></el-input-number>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="横坐标" placement="top-start">
            <el-button>上左</el-button>
            <el-input-number size="mini" v-model="imgx" class="imgx"></el-input-number>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="纵坐标" placement="top-start">
            <el-button>上左</el-button>
            <el-input-number size="mini" v-model="imgy" class="imgy"></el-input-number>
          </el-tooltip>
        </div>
      </div>

      <!-- 文本 -->
      <div v-if="tab==3" style="padding:0 20px 20px;">
        <el-input v-model="mingzi" type="textarea" :rows="2" placeholder="名字" class="input">
        </el-input>
        <!-- 名字纵轴 -->
        <el-tooltip class="item" effect="dark" content="横轴" placement="top">
          <el-input-number size="mini" v-model="namex" :step="10"></el-input-number>
        </el-tooltip>
        <!-- 名字横轴 -->
        <el-tooltip class="item" effect="dark" content="纵轴" placement="top">
          <el-input-number size="mini" v-model="namey" :step="10"></el-input-number>
        </el-tooltip>
        <!-- 名字体大小 -->
        <el-tooltip class="item" effect="dark" content="字体大小" placement="top">
          <el-input-number size="mini" v-model="namesize"></el-input-number>
        </el-tooltip>
        <!-- 字体加粗 -->
        <el-checkbox v-model="checked">是否加粗</el-checkbox>
        <!-- 颜色 -->
        <el-color-picker v-model="color1" size="mini" style="position: relative;top:10px;left:10px;">
        </el-color-picker>

        <!-- 电话 -->
        <el-input v-model="dianhua" type="textarea" :rows="2" placeholder="电话" class="input">
        </el-input>
        <!-- 电话纵轴 -->
        <el-tooltip class="item" effect="dark" content="横轴" placement="top">
          <el-input-number size="mini" v-model="TELx" :step="10"></el-input-number>
        </el-tooltip>
        <!-- 电话横轴 -->
        <el-tooltip class="item" effect="dark" content="纵轴" placement="top">
          <el-input-number size="mini" v-model="TELy" :step="10"></el-input-number>
        </el-tooltip>
        <!-- 名字体大小 -->
        <el-tooltip class="item" effect="dark" content="字体大小" placement="top">
          <el-input-number size="mini" v-model="Telsize1"></el-input-number>
        </el-tooltip>
        <!-- 字体加粗 -->
        <el-checkbox v-model="checked1">是否加粗</el-checkbox>
        <!-- 颜色 -->
        <el-color-picker v-model="color2" size="mini" style="position: relative;top:10px;left:10px;">
        </el-color-picker>

        <!-- 地址 -->
        <el-input v-model="dizhi" type="textarea" :rows="2" placeholder="地址" class="input">
        </el-input>
        <!-- 地址纵轴 -->
        <el-tooltip class="item" effect="dark" content="横轴" placement="top">
          <el-input-number size="mini" v-model="sitex" :step="10"></el-input-number>
        </el-tooltip>
        <!-- 地址横轴 -->
        <el-tooltip class="item" effect="dark" content="纵轴" placement="top">
          <el-input-number size="mini" v-model="sitey" :step="10"></el-input-number>
        </el-tooltip>
        <!-- 名字体大小 -->
        <el-tooltip class="item" effect="dark" content="字体大小" placement="top">
          <el-input-number size="mini" v-model="sitesize1"></el-input-number>
        </el-tooltip>
        <!-- 字体加粗 -->
        <el-checkbox v-model="checked2">是否加粗</el-checkbox>
        <!-- 颜色 -->
        <el-color-picker v-model="color3" size="mini" style="position: relative;top:10px;left:10px;">
        </el-color-picker>

        <el-input v-model="riqi" type="textarea" :rows="2" placeholder="日期" class="input">
        </el-input>
        <!-- 日期纵轴 -->
        <el-tooltip class="item" effect="dark" content="横轴" placement="top">
          <el-input-number size="mini" v-model="datex" :step="10"></el-input-number>
        </el-tooltip>
        <!-- 日期横轴 -->
        <el-tooltip class="item" effect="dark" content="纵轴" placement="top">
          <el-input-number size="mini" v-model="datey" :step="10"></el-input-number>
        </el-tooltip>
        <!-- 名字体大小 -->
        <el-tooltip class="item" effect="dark" content="字体大小" placement="top">
          <el-input-number size="mini" v-model="datesize1"></el-input-number>
        </el-tooltip>
        <!-- 字体加粗 -->
        <el-checkbox v-model="checked3">是否加粗</el-checkbox>
        <!-- 颜色 -->
        <el-color-picker v-model="color4" size="mini" style="position: relative;top:10px;left:10px;">
        </el-color-picker>
      </div>

      <!-- 上传 -->
      <div>
        <el-button type="danger" class="btn" @click="toImg">上传<i class="el-icon-upload el-icon--right"></i>
        </el-button>
      </div>
    </div>


  </div>
</body>

<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!-- 引入canvas -->
<script src="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.js"></script>
<script>
  new Vue({
    el: "#app",
    data: function () {
      return {
        dataURL: '', //
        activeIndex2: '1', //tab切换默认第一个高亮
        tab: 1, //当前选中的  1,2,3
        bgimg: [], //背景图
        bgwd: 475,
        bghi: 808,
        img1: [], //头像
        touw: 100,
        touh: 100,
        toux: 100,
        touy: 100,
        tour: 50,

        img2: [], //二维码
        imgw: 120,
        imgh: 120,
        imgx: 230,
        imgy: 600,

        visible: false,
        tabPosition: "top",
        input10: "",
        namex: "100",
        TELx: "100",
        sitex: "100",
        datex: "100",
        namey: "100",
        TELy: "150",
        sitey: "200",
        datey: "250",
        mingzi: "",
        riqi: "",
        dizhi: "",
        dianhua: "",
        namesize: "18",
        Telsize1: "18",
        sitesize1: "18",
        datesize1: "18",
        checked: false,
        checked1: false,
        checked2: false,
        checked3: false,
        color1: "#333",
        color2: "#333",
        color3: "#333",
        color4: "#333"
      };
    },
    watch: {
      bghi(newName, oldName) {
        document.querySelector(".bgimg").style.height = newName + "px";
      },
      bgwd(newName, oldName) {
        document.querySelector(".bgimg").style.width = newName + "px";
      },
      imgw(newName, oldName) {
        document.querySelector(".erweima").style.width = newName + "px";
      },
      imgh(newName, oldName) {
        document.querySelector(".erweima").style.height = newName + "px";
      },
      imgx(newName, oldName) {
        document.querySelector(".erweima").style.left = newName + "px";
      },
      imgy(newName, oldName) {
        document.querySelector(".erweima").style.top = newName + "px";
      },
      touw(newName, oldName) {
        document.querySelector(".tou").style.width = newName + "px";
      },
      touh(newName, oldName) {
        document.querySelector(".tou").style.height = newName + "px";
      },
      toux(newName, oldName) {
        document.querySelector(".tou").style.left = newName + "px";
      },
      touy(newName, oldName) {
        document.querySelector(".tou").style.top = newName + "px";
      },
      tour(newName, oldName) {
        document.querySelector(".tou").style.borderRadius = newName + "px";
      },
      namex(newName, oldName) {
        document.querySelector(".name").style.left = newName + "px";
      },
      namey(newName, oldName) {
        document.querySelector(".name").style.top = newName + "px";
      },
      namesize(newName, oldName) {
        document.querySelector(".name").style.fontSize = newName + "px";
      },
      Telsize1(newName, oldName) {
        document.querySelector(".Tel").style.fontSize = newName + "px";
      },
      sitesize1(newName, oldName) {
        document.querySelector(".site").style.fontSize = newName + "px";
      },
      datesize1(newName, oldName) {
        document.querySelector(".date").style.fontSize = newName + "px";
      },
      checked(newName, oldName) {
        if (newName) {
          document.querySelector(".name").style.fontWeight = 700;
        } else {
          document.querySelector(".name").style.fontWeight = 400;
        }
      },
      checked1(newName, oldName) {
        if (newName) {
          document.querySelector(".Tel").style.fontWeight = 700;
        } else {
          document.querySelector(".Tel").style.fontWeight = 400;
        }
      },
      checked2(newName, oldName) {
        if (newName) {
          document.querySelector(".site").style.fontWeight = 700;
        } else {
          document.querySelector(".site").style.fontWeight = 400;
        }
      },
      checked3(newName, oldName) {
        if (newName) {
          document.querySelector(".date").style.fontWeight = 700;
        } else {
          document.querySelector(".date").style.fontWeight = 400;
        }
      },
      color1(newName, oldName) {
        document.querySelector(".name").style.color = newName;
      },
      color2(newName, oldName) {
        document.querySelector(".Tel").style.color = newName;
      },
      color3(newName, oldName) {
        document.querySelector(".site").style.color = newName;
      },
      color4(newName, oldName) {
        document.querySelector(".date").style.color = newName;
      },
      sitex(newName, oldName) {
        document.querySelector(".site").style.left = newName + "px";
      },
      sitey(newName, oldName) {
        document.querySelector(".site").style.top = newName + "px";
      },
      Telx(newName, oldName) {
        document.querySelector(".site").style.top = newName + "px";
      },
      datex(newName, oldName) {
        document.querySelector(".date").style.left = newName + "px";
      },
      datey(newName, oldName) {
        document.querySelector(".date").style.top = newName + "px";
      },
      TELx(newName, oldName) {
        document.querySelector(".Tel").style.left = newName + "px";
      },
      TELy(newName, oldName) {
        document.querySelector(".Tel").style.top = newName + "px";
      }
    },

    methods: {
      // 点击tab切换
      handleSelect(key, keyPath) {
        console.log(key, keyPath);
        this.tab = key
      },
      // 点击上传,获取图片url
      toImg() {
        let that = this
        html2canvas(document.querySelector('.leftimg')).then(canvas => {
          let imgUrl = canvas.toDataURL('image/png');
          console.log(imgUrl);
          that.dataURL = imgUrl;
        }).catch(error => {})
      },
      /*将base64转换为file*/
      dataURLtoFile(dataurl, filename) { //将base64转换为文件
        var arr = dataurl.split(','),
          mime = arr[0].match(/:(.*?);/)[1],
          bstr = atob(arr[1]),
          n = bstr.length,
          u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n);
        }
        return new File([u8arr], filename, {
          type: mime
        });
      },

      // ajax上传图片——文件流方式
      upload(base64, name) {
        return new Promise((resolve, reject) => {
          let file = dataURLtoFile(base64, name);
          // 实例化FormData
          var formdata = new FormData();
          // 将文件信息存入formdata,键名为file
          // formdata会将文件信息序列化为ajax可识别的数据类型
          formdata.append("file", file);
          $.ajax({
            type: "post",
            url: `${baseURL}/api/common/upload?token=${localStorage.getItem('token')}`,
            data: formdata, // formdata直接赋值给data
            processData: false, //formdata已将数据序列化,无需在处理
            contentType: false, //formdata无需设置请求头
            success: function (res) {
              resolve(res.data)
            }
          });
        })
      }

    }
  });
</script>

</html>
Logo

前往低代码交流专区

更多推荐