前端图片拼接

这个博客介绍了一个在线图片拼接工具的实现,使用HTML5的拖放功能和Canvas API进行图片处理。用户可以选择或拖放图片,然后选择横向或纵向拼接方式,最后下载生成的拼接图片。代码中包含关键的JavaScript函数,如`filesToInstances`用于将文件转换为图片实例,`drawImages`用于在Canvas上绘制并拼接图片,以及下载功能的实现。
摘要由CSDN通过智能技术生成

此处图片拼接分为横向拼接与纵向拼接,
成品网站:https://www.onlinedo.cn/img-concat

直接上代码:
html

<h1 class="mainIndex_title">图片拼接</h1>
<div class="imgConcat_main">
  <div class="dragImgBox" id="dropZone">请拖拽本地图片文件到此处</div>
  <div class="imgConcat_btn">
    <span class="imgConcat_btn_choose">选择文件</span>
    <input id="upload-input" type="file" accept="image/*" multiple="multiple" style="display: none;">
    <!-- <span class="imgConcat_btn_concat">拼接</span> -->
    <a class="imgConcat_btn_download" style="display: none;">下载</a>
    <p class="imgConcat_type">
      拼接方向:
      <select name="" id="">
        <option value="1">纵向</option>
        <option value="2">横向</option>
      </select>
    </p>
  </div>
  <div id="image-container"></div>
</div>

js

 // 拼出来的图片的宽度
 let width = 10;
 // 拼出来的图片的高度
 let height = 10;
 // 拼出来的图片的质量,0-1之间,越大质量越好
 const encoderOptions = 1
 //横向拼接还是纵向拼接 1为纵向,2为横向
 let concatStyle = 1;
 let imgArr = [];   //图片集合
 let downLoadBase64;
const uploadInput = document.getElementById('upload-input')
const imageDiv = document.getElementById('image-container')
 // 下载
 $(".imgConcat_btn_download").click(function(){
   if(u_login!==1){
     no_login();
   }else{
     downLoad(downLoadBase64,"concat_img.png")
   }
 })
 $(".imgConcat_btn_choose").click(function(){
   $("#upload-input").click();
 })
 $(".imgConcat_type select").change(function(){
   concatStyle = $(this).find("option:selected").val();
   imgConcat(imgArr)
 })
 uploadInput.addEventListener('change', event => {
     const files = Array.from(event.target.files)
     for(var i=0;i<files.length;i++){
       imgArr.push(files[i]);
     }
     imgConcat(imgArr)
 })
 // 拖拽文件
 var dp = document.querySelector( '#dropZone' );
 document.addEventListener('drop', function (e) {
     e.preventDefault()
 }, false)
 document.addEventListener('dragover', function (e) {
     e.preventDefault()
 }, false)
 if(dp==null){
     return;
 }
 dp.addEventListener('dragover', function(e) {
     e.stopPropagation();
     e.preventDefault();
     e.dataTransfer.dropEffect = '导入';
 });
 dp.addEventListener("drop", function(e) {
     e.stopPropagation();
     e.preventDefault();
     // var file = e.dataTransfer.files;
     const dpfiles = Array.from(e.dataTransfer.files)
     // var fileName = file[0].name;
     // var fileType = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
     // if(fileType!=="png"&&fileType!=="jpg"&&fileType!=="webp"&&fileType!=="gif"&&fileType!=="jpeg"&&fileType!=="bmp"){
     //   alert("请上传图片格式")
     // }else{
       for(var i=0;i<dpfiles.length;i++){
         imgArr.push(dpfiles[i]);
       }
       imgConcat(imgArr)
     // }
 });
 function imgConcat(files){
   var file = files[0];
   var img = new Image();
   var reader = new FileReader();
   if (file.type.indexOf("image") == 0) {
       reader.readAsDataURL(file);
   }
   // 文件base64化,以便获知图片原始尺寸
   reader.onload = function(e) {
     img.src = e.target.result;
     img.onload = function(){
       width = this.width;
       height = this.height;
     }
   }
   filesToInstances(files, instances => {
       drawImages(instances, finalImageUrl => {
           imageDiv.innerHTML = `<div><img src=${finalImageUrl}></div>`
           // $(".imgConcat_btn_download").attr("href",finalImageUrl);
           downLoadBase64 = finalImageUrl
           console.log(downLoadBase64)
           // $(".imgConcat_btn_download").attr("download","concat_img");
           $(".imgConcat_btn_download").show();
       })
   })
 }
 function dataURIToBlob(dataURI) {
   var binStr = atob(dataURI.split(',')[1]),
     len = binStr.length,
     arr = new Uint8Array(len);

   for (var i = 0; i < len; i++) {
     arr[i] = binStr.charCodeAt(i);
   }
   return new Blob([arr])
 }
 
 function downLoad(base,name){
   const bloburl = dataURIToBlob(base)
   var downloadElement = document.createElement("a");
   downloadElement.href =  URL.createObjectURL(bloburl);
   downloadElement.download = name; //下载后文件名
   document.body.appendChild(downloadElement);
   downloadElement.click(); //点击下载
   document.body.removeChild(downloadElement); //下载完成移除元素
   window.URL.revokeObjectURL(downloadElement.href); //释放掉blob对象
 }

 // 根据图片文件拿到图片实例
 const filesToInstances = (files, callback) => {
     const length = files.length
     let instances = []
     let finished = 0

     files.forEach((file, index) => {
         const reader = new FileReader()
         // 把文件读为 dataUrl
         reader.readAsDataURL(file)
         reader.onload = e => {
             const image = new Image()
             image.src = e.target.result
             image.onload = () => {
                 // 图片实例化成功后存起来
                 instances[index] = image
                 finished ++
                 if (finished === length) {
                     callback(instances)
                 }
             }
         }
     })
 }

   // 拼图
 const drawImages = (images, callback) => {
   if(concatStyle==1){
     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
     })
     callback(canvas.toDataURL('image/png', encoderOptions))
   }else{
     const widths = images.map(item => height /item.height  * item.width);
     const canvas = document.createElement('canvas')
     canvas.height = height
     canvas.width = widths.reduce((total, current) => total + current)
     const context = canvas.getContext('2d')
     let x = 0
     images.forEach((item, index) => {
         const width = widths[index]
         context.drawImage(item, x, 0, width, height)
         x += width
     })
     callback(canvas.toDataURL('image/png', encoderOptions))
   }
     
   
 }

主要处理方法就是:


 // 根据图片文件拿到图片实例
    const filesToInstances = (files, callback) => {
        const length = files.length
        let instances = []
        let finished = 0

        files.forEach((file, index) => {
            const reader = new FileReader()
            // 把文件读为 dataUrl
            reader.readAsDataURL(file)
            reader.onload = e => {
                const image = new Image()
                image.src = e.target.result
                image.onload = () => {
                    // 图片实例化成功后存起来
                    instances[index] = image
                    finished ++
                    if (finished === length) {
                        callback(instances)
                    }
                }
            }
        })
    }

      // 拼图
    const drawImages = (images, callback) => {
      if(concatStyle==1){  //此处是纵向拼图处理
        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
        })
        callback(canvas.toDataURL('image/png', encoderOptions))
      }else{  //此处是横向拼图处理
        const widths = images.map(item => height /item.height  * item.width);
        const canvas = document.createElement('canvas')
        canvas.height = height
        canvas.width = widths.reduce((total, current) => total + current)
        const context = canvas.getContext('2d')
        let x = 0
        images.forEach((item, index) => {
            const width = widths[index]
            context.drawImage(item, x, 0, width, height)
            x += width
        })
        callback(canvas.toDataURL('image/png', encoderOptions))
      }
        
      
    }

调用:

 filesToInstances(files, instances => {
     drawImages(instances, finalImageUrl => {
         imageDiv.innerHTML = `<div><img src=${finalImageUrl}></div>`
         // $(".imgConcat_btn_download").attr("href",finalImageUrl);
         downLoadBase64 = finalImageUrl
         console.log(downLoadBase64)
         // $(".imgConcat_btn_download").attr("download","concat_img");
         $(".imgConcat_btn_download").show();
     })
 })

只需要把图片文件数组传入即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值