【多个图片合成一张图片】vue简单实现多张图片合并成一张图并下载图片功能,html2canvas下载图片跨域问题解决【详细注释,复制即用】

本文介绍如何使用html2canvas将两张图片合成为一张,并提供下载功能。通过调整DOM元素样式,实现图片的精确布局。

前言

最近接到的一个小需求,是需要两个图片合成一张图片
然后可以下载下来变成一张完整的图的
我就在网上看了下,发现html2canvas可以完成这个功能
那就做一个小案例记录一下这个功能,以前还没做过呢。以后再用到可以直接复制了。

效果图

这里是没有上传图片的时候
在这里插入图片描述
上传了图片的时候,两个图片叠加在一起,位置我自己调整了。
这里我添加了上传图片的功能。删除图片下面海报图内也会一起删掉

下载图片的时候,点击下载会下载下来合并后的图片
在这里插入图片描述

如果你们想要这个图测试一下的话,这里丢上来自己复制。
然后二维码因为这里帖子检测不让放出来,所以自行网上找一个图把。
在这里插入图片描述

首先你需要下载一下html2canvas

npm install html2canvas --save

完整代码

这里解释几点(防止刚接触的人看不懂):
1,我在img标签上放了crossorigin="anonymous"这句话意思是允许跨域,因为有些图片可能会出现不同源不允许下载的情况,添加这个可以下载
2,这里下载合并,其实你可以理解为,我就是把这个dom的内容截图了下来,这里#test这个dom内的所有元素包含写的文字和图片,都是直接被截图下来了。所以你可以自定义设置里面的样式。比如文字放哪里,图片放哪里。然后下载的时候就会按照你页面上的样子直接原封不动的下载下来,同理,这里图片也不是只能一张,你也可以弄好多张一起,循环出来一堆图片都没问题。这个自己设置调整一下位置就行了。
3,这个要下载的dom建议最好设置大小,或者你可以背景图填充满。因为如果不设置大小,dom会默认按照全屏大小也就是宽100%。那你的图片有可能宽并没有达到全屏那么大。
那就会出现一大块空白,而当你下载的时候下的是这个dom内的一切,所以这个空白也会被下载下来。那就不好看了。所以建议设置大小或者填充满。

最后,如果你复制这个代码后,可能会因为没有后台不能上传图片,想要试一下效果,那就忽略上传图片的功能。直接把你本地的两个图片引入地址放到img1和img2上就可以看效果了。

<template>
  <div>
    <el-form :model="form">
      <el-form-item label="背景图" :label-width="formLabelWidth">
        <el-upload
          class="avatar-uploader"
          action="http://xxxxxxx.cn/gzh/uploadFile"
          :data="{ image_class_id: '2', file_type: '1' }"
          name="img"
          :headers="{ token: 'db0044f0d0bbdce0a8e7dc4ca661bdbaa3e127ae' }"
          ref="upload"
          :file-list="ruleForm.imgList"
          :on-success="uploadSuccess"
          :on-remove="uploadRmove"
          list-type="picture-card"
          :limit="1"
        />
      </el-form-item>
      <el-form-item label="详情图" :label-width="formLabelWidth">
        <el-upload
          class="avatar-uploader"
          action="http://xxxxxxx.cn/gzh/uploadFile"
          :data="{ image_class_id: '2', file_type: '1' }"
          name="img"
          :headers="{ token: 'db0044f0d0bbdce0a8e7dc4ca661bdbaa3e127ae' }"
          ref="upload2"
          :file-list="ruleForm.imgList2"
          :on-success="uploadSuccess2"
          :on-remove="uploadRmove2"
          list-type="picture-card"
          :limit="1"
        />
      </el-form-item>
    </el-form>
    <el-button @click="downBtn">下载</el-button>
    <div
      id="test"
      :style="'background-image:url(' + img1 + ');background-repeat: no-repeat'"
    >
      <p style="text-align: center; font-size: 20px">海报图</p>
      <!-- 这里重点:crossorigin="anonymous"这句话意思是允许跨域,因为有些图片可能会出现不同源不允许下载的情况,添加这个可以下载 -->
      <img :src="img2" alt="" class="centerImg" crossorigin="anonymous" />
    </div>
  </div>
</template>

<script>
import html2canvas from "html2canvas"; //引入组件  需要先下载 npm install html2canvas --save
export default {
  data() {
    return {
      form: "",
      formLabelWidth: "120px",

      posterImg: "", //base64图片地址
      img1: "", //图片1
      img2: "", //图片2

      //下面的是上传图片组件用到的
      ruleForm: {
        imgList: [],
        imgList2: [],
      },
      mapListed: [],
      mapListed2: [],
    };
  },
  methods: {
    //合成并下载图片
    downBtn() {
      //获取dom,这里合成图片是这个dom内的一切元素都会一起合成一个图片下载下来,包含里面的文字和图片,所以可以自行调整这个dom内的内容,包括文字和图片样式等,相当于就是把这个div的内容截图下来了
      let dom = document.getElementById("test");
      //调用方法下载
      html2canvas(dom, {
        useCORS: true, //这个为true代表允许跨域
        allowTaint: false,
        logging: false,
        letterRendering: true,
      }).then((canvas) => {
        this.posterImg = canvas.toDataURL("image/png"); //转base64
        let a = document.createElement("a"); // 生成一个a元素
        let event = new MouseEvent("click"); // 创建一个单击事件
        a.download = "photo"; // 设置图片名称
        a.href = this.posterImg; // 将生成的URL设置为a.href属性
        a.dispatchEvent(event); // 触发a的单击事件
      });
    },
    //第一个图上传成功
    uploadSuccess(response, file, fileList) {
      let that = this;
      console.log(1111111);
      if (response.code == "201") {
        console.log(22222);
        that.$nextTick(() => {
          console.log(333333);
          let mainImg = that.$refs.upload;
          if (mainImg) {
            mainImg.uploadFiles.forEach((element, index) => {
              if (file.uid == element.uid) {
                mainImg.uploadFiles.splice(index, 1);
              }
            });
          }
        });
        that.$alert(response.message);
        return;
      }
      that.$message({
        message: "上传成功",
        type: "success",
      });
      //拿到后台传过来的url图片渲染上去
      this.img1 = response.data.url;
      console.log(this.img1);
      that.mapListed.push(response);
    },
    //删除图片
    uploadRmove(file, fileList) {
      this.ruleForm.imgList = [];
      this.img1 = "";
      this.mapListed.splice(0, 1);
    },
    //第二个图上传成功
    uploadSuccess2(response, file, fileList) {
      let that = this;
      if (response.code == "201") {
        that.$nextTick(() => {
          let mainImg = that.$refs.upload2;
          if (mainImg) {
            mainImg.uploadFiles.forEach((element, index) => {
              if (file.uid == element.uid) {
                mainImg.uploadFiles.splice(index, 1);
              }
            });
          }
        });
        that.$alert(response.message);
        return;
      }
      that.$message({
        message: "上传成功",
        type: "success",
      });
      //拿到后台传过来的url图片渲染上去
      this.img2 = response.data.url;
      console.log(this.img2);
      that.mapListed2.push(response);
    },
    //删除图片
    uploadRmove2(file, fileList) {
      this.ruleForm.imgList2 = [];
      this.img2 = "";
      this.mapListed2.splice(0, 1);
    },
  },
};
</script>

<style>
/* 设置盒子的大小,如果不设置,下载下来的截图会是按全屏大小来的,如果图片没有铺满,会把空白处一起下载下来。 */
#test {
  width: 400px;
  height: 600px;
}
/* 调整二维码图片的位置 */
.centerImg {
  width: 80px;
  margin: 425px 0 0 180px;
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

接口写好了吗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值