• vue.js3: 多张图片合并(vue@3.2.37)


    一,安装用到的第三方库

    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
    image2pdf@0.1.0 /data/vue/pdf/image2pdf
    └── vuedraggable@4.1.0

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


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

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

    说明:作者:刘宏缔 邮箱: 371125307@qq.com

    二,js代码:

    <template>
    <div>
      <div style=" 800px;margin: auto;">
        <div style="margin-top: 10px;">
          选择图片(可多选):
          <input type="file" ref="hiddenfile" accept="image/*" multiple @change="handleFile" class="hiddenInput" />
        </div>
    
        <div style="400px;margin: auto;margin-top: 10px;">
          <div style="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="400px;display:block;" />
                <div @click="del(index)"
                     style="40px;height:40px;position: absolute;top:0px;right:0px;">
                  <el-icon style="font-size: 20px;color:white;opacity:0.8;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="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+";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
    image2pdf@0.1.0 /data/vue/pdf/image2pdf
    ├─┬ @vue/cli-plugin-babel@5.0.8
    │ └─┬ @vue/babel-preset-app@5.0.8
    │   ├─┬ @vue/babel-preset-jsx@1.3.0
    │   │ └── vue@3.2.37 deduped invalid: "2.x" from node_modules/@vue/babel-preset-jsx
    │   └── vue@3.2.37 deduped
    └─┬ vue@3.2.37
      └─┬ @vue/server-renderer@3.2.37
        └── vue@3.2.37 deduped
  • 相关阅读:
    【linux 文件管理】7-文件重定向
    by David Bombal CCNA with kali linux
    【linux 文件管理】6-软链接和硬链接
    13.mysql索引的使用
    11.mysql SQL优化之SQL问题定位
    mysql服务常用命令
    10.mysql存储引擎
    9. Mysql的体系结构概览
    8.mysql触发器
    项目上线部署
  • 原文地址:https://www.cnblogs.com/architectforest/p/16640272.html
Copyright © 2020-2023  润新知