vue canvas拼接图片(纵向)

前端 专栏收录该内容
10 篇文章 0 订阅

vue 图片竖向拼接组件代码

底部有demo

<template>
  <div>
    <div>
      <input
        type="file"
        id="upFile"
        @change="upFile($event)"
        accept="image/*"
        multiple="multiple"
        style="display:none"
      />
      <label for="upFile">
        <span class="choosefile-btn">选择文件</span>
      </label>
    </div>
    <div v-if="isPreview">
      <img :src="imgurl" style="width:100%" />
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      returnData: null,
      imgurl: null,
    };
  },
  props: {
    isPreview: {
      type: Boolean,
      required: false,
      default: true,
    },
    isAutoDownload: {
      type: Boolean,
      required: false,
      default: false,
    },
    returnType: {
      type: String,
      required: false,
      default: "base64",
      validator: (value) => {
        return ["base64", "file"].indexOf(value) !== -1;
      },
    },
    widths: {
      type: [String, Number],
      required: false,
      default: 1366,
    },
    quality: {
      type: [String, Number],
      required: false,
      default: 0.618,
    },
  },
  methods: {
    base64ToBlob(code) {
      let parts = code.split(";base64,");
      let contentType = parts[0].split(":")[1];
      let raw = window.atob(parts[1]);
      let rawLength = raw.length;
      let uInt8Array = new Uint8Array(rawLength);

      for (let i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
      }
      return new Blob([uInt8Array], { type: contentType });
    },
    downloadFile(fileName, content) {
      let aLink = document.createElement("a");
      let blob = this.base64ToBlob(content); // new Blob([content]);
      let evt = document.createEvent("HTMLEvents");
      evt.initEvent("click", true, true); // initEvent 不加后两个参数在FF下会报错  事件类型,是否冒泡,是否阻止浏览器的默认行为
      aLink.download = fileName;
      aLink.href = URL.createObjectURL(blob);
      aLink.dispatchEvent(
        new MouseEvent("click", {
          bubbles: true,
          cancelable: true,
          view: window,
        })
      ); // 兼容火狐
    },

    upFile() {
      if (this.returnType !== "file") {
        const files = Array.from(event.target.files);
        this.filesToInstances(files);
      } else {
        this.returnData = event.target.files;
        this.returnRes();
      }
    },
    filesToInstances(files) {
      const length = files.length;
      let instances = [];
      let finished = 0;

      files.forEach((file, index) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = (e) => {
          const image = new Image();
          image.src = e.target.result;
          image.onload = () => {
            // 图片实例化成功后存起来
            instances[index] = image;
            finished++;
            if (finished === length) {
              this.drawImages(instances);
            }
          };
        };
      });
    },
    drawImages(images) {
      const width = this.widths;
      const heights = images.map((item) => (width / item.width) * item.height);
      const canvas = document.createElement("canvas");
      canvas.width = width;
      canvas.height = heights.reduce((total, current) => total + current);
      const context = canvas.getContext("2d");

      let y = 0;

      images.forEach((item, index) => {
        const height = heights[index];
        context.drawImage(item, 0, y, width, height);
        y += height;
      });
      const base64Url = canvas.toDataURL("image/jpeg", this.quality);

      this.dealImages(base64Url);
      if (this.returnType == "base64" && this.isAutoDownload) {
        this.downloadFile(this.createFileName(), base64Url);
      }
    },
    dealImages(url) {
      this.imgurl = url;
      this.returnData = url;
      this.returnRes();
    },
    returnRes() {
      this.$emit("getRes", this.returnData);
    },
    createFileName() {
      return "图片拼接" + new Date().getTime();
    },
  },
};
</script>

<style>
.choosefile-btn {
  display: inline-block;
  padding: 10px 20px;
  margin-top: 40px;
  background: rgb(83, 170, 148);
  border-radius: 8px;
  color: #efeefe;
}
</style>

使用

<Splicing :isPreview="true" @getRes="getSpellData"/>
...
import Splicing from '@/components/Splicing.vue';
components: {
    Splicing
  },
  getSpellData(e){
  //返回的base64或者file结果
      console.log(e);
    },

react拼接图片代码:react拼接图片代码

angular拼接图片代码:angular拼接图片代码

demo地址(vue):demo

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值