首页 > 其他分享 >vue.js3: 多张图片合并([email protected])

vue.js3: 多张图片合并([email protected])

时间:2022-08-30 17:58:53浏览次数:84  
标签:vue const 37 3.2 time var let 图片

一,安装用到的第三方库

1,安装:
liuhongdi@lhdpc:/data/vue/pdf/image2pdf$ npm i -S vuedraggable@next
 
added 2 packages in 11s

2,查看已安装的版本:

liuhongdi@lhdpc:/data/vue/pdf/image2pdf$ npm list vuedraggable@next
[email protected] /data/vue/pdf/image2pdf
└── [email protected]

说明:此第三方库仅供在操作时拖动排序使用,与图片的合并无关


说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

         对应的源码可以访问这里获取: https://github.com/liuhongdi/
         或: https://gitee.com/liuhongdi

说明:作者:刘宏缔 邮箱: [email protected]

二,js代码:

<template>
<div>
  <div style="width: 800px;margin: auto;">
    <div style="margin-top: 10px;">
      选择图片(可多选):
      <input type="file" ref="hiddenfile" accept="image/*" multiple @change="handleFile" class="hiddenInput" />
    </div>

    <div style="width:400px;margin: auto;margin-top: 10px;">
      <div style="width:400px;font-size:12px;">可以拖动图片改变顺序</div>
      <draggable
          :list="selFiles"
          item-key="id"
          class="list-group"
          ghost-class="ghost"
          @start="dragging = true"
          @end="dragging = false"
      >
        <template #item="{ element,index }">
          <div class="list-group-item">
            <img class="fg" :id="'fg'+element.id" :src="element.fileimg" style="width:400px;display:block;" />
            <div @click="del(index)"
                 style="width:40px;height:40px;position: absolute;top:0px;right:0px;">
              <el-icon style="font-size: 20px;color:white;opacity:0.8;width:40px;height:40px;">
                <Delete />
              </el-icon>
            </div>
          </div>
        </template>
      </draggable>
    </div>
    <div>
      <el-button ref="downButtonRef" :disabled="buttonEnable === true  ?  false : true" type="info" plain
                 @click="down" style="width:400px;margin-top: 10px;">合并图片并下载</el-button>
    </div>
    
  </div>
</div>
</template>

<script>
import {ref} from "vue"
import draggable from "vuedraggable";
export default {
  name: "ImageMerge",
  components: {
    draggable,
  },
  setup() {
    //最大高度和最大宽度
    let maxWidth = 0;
    let maxHeight = 0;
    //选中的图片文件,保存在数组中
    const selFiles = ref([]);
    //得到各图片的最大高度和最大宽度
    const getImgMaxWidthHeight = () => {
      //let allHeight = 0;
      for( var i=0;i<selFiles.value.length; i++ ){
        let one = selFiles.value[i];
        //得到高度
        let img = document.getElementById("fg"+one.id);
        let width = img.naturalWidth;
        let height = img.naturalHeight;
        console.log("width:"+width+";height:"+height);
        if (width>maxWidth) {
            maxWidth = width;
        }
        if (height > maxHeight) {
          maxHeight = height;
        }
      }
      console.log("maxWidth:"+maxWidth+";maxHeight:"+maxHeight);
    }

    //垂直方向合并时,得到高度:
    const getImgDestHeight = () => {
      let allHeight = 0;
      for( var i=0;i<selFiles.value.length; i++ ){
        let one = selFiles.value[i];
        //得到高度
        let img = document.getElementById("fg"+one.id);
        let width = img.naturalWidth;
        let height = img.naturalHeight;
        let destHeightOne = (maxWidth * height) / width;
        allHeight = allHeight+destHeightOne;
      }
      console.log("allHeight:"+allHeight);
      return allHeight;
    }
    
    //下载pdf
    const down = async () => {
      getImgMaxWidthHeight();
      
      //得到合并后图片的高度
      let destHeight = getImgDestHeight();
      console.log("destHeight:"+destHeight);

      //生成合并后图片
      const canvas = document.createElement('canvas')
      canvas.width = maxWidth;
      canvas.height = destHeight;
      const context = canvas.getContext('2d');

      let top = 0;
      //合并图片
      for( var i=0;i<selFiles.value.length; i++ ) {
        console.log(i);
        let one = selFiles.value[i];
        //得到当前图片的高度
        let img = document.getElementById("fg"+one.id);
        let width = img.naturalWidth;
        let height = img.naturalHeight;
        let destHeightOne = (maxWidth * height) / width;
        context.drawImage(img, 0, top, maxWidth, destHeightOne);
        top = top+destHeightOne;
      }
      //下载图片
      downJpgByCanvas(canvas);
    }
    
    //下载图片
    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(); // 下载之后把创建的元素删除
    }
    
    //选中图片时,把图片添加到数组
    const handleFile = (e) => {
      let filePaths = e.target.files;
      //清空原有缩略图
      if (filePaths.length === 0) {
        //未选择,则返回
        return
      } else {
        //清空数组中原有图片
        selFiles.value.length = 0;
      }
      //把新选中的图片加入数组
      for( var i=0;i<filePaths.length; i++ ){
        let file = filePaths[i];
        var reader = new FileReader();
        reader.readAsArrayBuffer(file);
        //reader.
        let one = {
          id:i,
          fileimg:URL.createObjectURL(file),  //预览用
          file:file,
        }
        selFiles.value[i] = one;
      }
      setButton();
    }

    //设置下载button是否可用
    const buttonEnable = ref(false);
    const setButton = () => {
      console.log("files length:"+selFiles.value.length);
      if (selFiles.value.length>0) {
        buttonEnable.value = true;
      } else {
        buttonEnable.value = false;
      }
    }
    
    //补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 {
      down,
      handleFile,
      selFiles,
      buttonEnable,
    }
  }
}
</script>

<style scoped>

</style>

三,测试效果:

界面: 合并后的图片:

四,查看vue框架的版本:

liuhongdi@lhdpc:/data/vue/pdf/image2pdf$ npm list vue
[email protected] /data/vue/pdf/image2pdf
├─┬ @vue/[email protected]
│ └─┬ @vue/[email protected]
│   ├─┬ @vue/[email protected]
│   │ └── [email protected] deduped invalid: "2.x" from node_modules/@vue/babel-preset-jsx
│   └── [email protected] deduped
└─┬ [email protected]
  └─┬ @vue/[email protected]
    └── [email protected] deduped

 

标签:vue,const,37,3.2,time,var,let,图片
From: https://www.cnblogs.com/architectforest/p/16640272.html

相关文章

  • vue 跳转页面时报错: NavigationDuplicated: Avoided redundant navigation to current
    vue-router路由重复的解决方法:在router文件夹下面的index.js中加上下面几句代码:importVueRouterfrom'vue-router' constoriginalPush=......
  • vue+element增加
    <el-button         @click="增加的方法"> <el-form        :model="formData"> <el-table        :data=......
  • vue-cli安装错误的记录
    错误是由于想升级vue-cli引起的npmERR!Invalidtagname"@vue-cli":TagsmaynothaveanycharactersthatencodeURIComponentencodes.  仔细一看npminstal......
  • 自己玩KAFKA 版本 kafka_2.13-3.2.1
       好久没有研究Kafka了,重新摸起来自己在虚机中 、环境JDK8+kafka_2.13-3.2.1不太建议使用Windows,除非迫不得已,毕竟Kafka的使用场景都是高并发场景,Windows服务......
  • Jenkins+SpringCloud(多模块)+Vue项目详细配置
    一、Jenkins安装及所需插件安装   安装过程略。   我这用到工具包括JDK、Git、Maven、NodeJS:可以选择自行在服务器安装,也可以通过Jenkins自动安装,位置在系统......
  • vue3+ pinia 的初实用
    固定不变的:stores/index.jsimport{createPinia}from"pinia"constpinia=createPinia()exportdefaultpinia main.jsimport{createApp}from......
  • vue路由拦截器
    vue路由拦截器有三种路由拦截器:全局的,针对单个路由的,针对单个组件的1.全局的路由拦截器写在router下的index.js的exportdefaultrouter之前的代码。前置拦截器:route......
  • vue3 Teleport 传送门
    先放个官方文档链接~某位同事研究vue3时,发现vue3的Teleport使用起来有点问题。<template><divclass="test">1<divclass="qwe">2</div><teleportto=".q......
  • vue2和vue3的modules :
    store/modules/home.jsexportdefault{state:{//服务器数据banners:[],recommends:[]},mutations:{changeBanners(state,banners......
  • vite+vue2 的学习与问题记录
    描述按照博文[https://juejin.cn/post/6988808776291713060]指导步骤执行完成。问题记录运行npmrundev控制台显示failedtoloadconfigfrom/Users/study-vite-vu......