使用h5的canvas实现两张图片的合并

本文介绍了如何利用HTML5的Canvas元素实现两张图片的合并。首先确保图片加载完成,然后利用Canvas的drawImage()方法将图片绘制到画布上,并通过toDataURL()生成合并后的图片数据。需要注意的是,要获取图片原始值,设置画布尺寸与最大图片相同,并处理图片加载可能出现的错误。在jQuery中,务必使用$()包裹元素以避免错误。

思路:
1.首先等待图片加载完成
2.然后使用canvas完成图片的合并
3.显示合成图片
步骤:
1.根据第一个思路,需要image的load和error事件,大致流程:
var l_image = new Image();
l_image.src = src;
l_image.onload = function () {};
l_image.onerror = function () {};
2,根据第二个思路,需要canvas的drawImage()和toDataURL()两个方法,大致流程:
先试用for循环依次将图片写入画布,然后使用toDataURL生成新的图片(返回值可以作为图片的路径)
3.根据需要是否显示合成图片:
代码:

$(function () {
   var $imgs = $('.img-boxs .merging'),
       $btnMerge = $('#btn-merge'),
       $mergedImage = $('.img-boxs .merged')[0],
       srcs = [],
       arr_img_w = [],
       arr_img_h = [],
       imgs_num = $imgs.length,
       loaded_img = 0;
   /*
   * 定义一个名为loading的函数,用于加载图片以及获取一些初始值
   * @param    void
   * @return   void
   * */
   var loading = function () {
       for (var i = 0; i < imgs_num; i++) {
           try{
               if (!$($imgs[i])) {
                   throw 'loading函数参数$imgs['+i+']不能为空';
               }
               srcs[i] = $($imgs[i]).attr("src");
               var _image = new Image();
               _image.src = srcs[i];
               //保存图片的原始宽高
               arr_img_w.push(_image.width);
               arr_img_h.push(_image.height);
               //不论图片加载完成还是失败都执行该函数
               $(_image).on('load error', function () {
                   loadImage();
               });
           } catch (err) {
               printError(err);
           }
       }
       function loadImage () {
           if (imgs_num === loaded_img) {
               return false;
           }
           loaded_img = Math.min(imgs_num, ++loaded_img);
       }
   };

   loading();

   $btnMerge.on('click', function () {
        mergeImages();
   });

    /*
    * 定义一个名为mergeImages的函数,用于合并两张图片
    * @param    void
    * @return   void
    * */
   function mergeImages () {
       try {
           if (loaded_img!==imgs_num && 2!==imgs_num) {
               throw '图片未加载完成或图片的数目不为2';
               return false;
           }
           var canvas = document.createElement('canvas'),
               temp_w = 0,
               temp_h = 0,
               offset_w = Math.abs((arr_img_w[0] - arr_img_w[1]) / 2),//最后一张图片居中需要的x轴移动值
               offset_h = Math.abs((arr_img_h[0] - arr_img_h[1]) / 2),//最后一张图片居中需要的y轴移动值
               l_src = '',
               ctx = {};
           //画布的宽度和高度和最大图片的一样
           canvas.width = getMaxofArray(arr_img_w);
           canvas.height = getMaxofArray(arr_img_h);
           ctx = canvas.getContext('2d');
           for (var i = 0; i < imgs_num; i++) {
               temp_w = arr_img_w[i];
               temp_h = arr_img_h[i];
               if (i == (imgs_num-1)) {
                   ctx.drawImage($imgs[i], 0, 0, temp_w, temp_h, offset_w, offset_h, temp_w, temp_h);
               } else {
                   ctx.drawImage($imgs[i], 0, 0, temp_w, temp_h, 0, 0, temp_w, temp_h);
               }
           }
           l_src = canvas.toDataURL('image/png');
           $($mergedImage).attr('src', l_src);
       } catch (err) {
           printError(err);
       }
   }

    /*
     * 定义一个名为getMaxofArray的函数,用于获取数组中的最大值
     * @param    array     elems        需要获取最大值的数组
     * @return   boolean   maxValue     返回最大值
     * */
   function getMaxofArray (elems) {
       try {
           if (!Array.isArray(elems)) {
               throw 'getMaxofArray函数的参数必须是数组';
           }
       } catch (err) {
           printError(err);
       }
       return Math.max.apply(null, elems);
   }

    /*
     * 定义一个名为getMaxofArray的函数,用于获取数组中的最大值
     * @param    string     msg     产生的异常或错误
     * @return   void
     * */
   function printError (msg) {
       console.log('error message:', msg);
   }
});

这里写图片描述
这里写图片描述
注意:
1.要获取图片的原始值而不是css样式,所以你可以在var image = new Image(),后取得图片的原始值,
2.画布的宽高应和最大图片的宽高一致
3.图片不仅要写load事件,还要写error事件

错误
如何控制显示这样的错误

$imgs[i].attr is not a function
    at loading (mergeImages.js:21)
    at HTMLDocument.<anonymous> (mergeImages.js:43)
    at mightThrow (jquery-3.2.1.js:3583)
    at process (jquery-3.2.1.js:3651)

你会好奇找了一圈,你会有没什么错误啊,jquery明明有这个方法啊等等的想法
首先你要明确,你肯定有错,不然不会有错误,
其次使用console.log()打印元素会显示dom元素,恭喜你,你离真相只有一步,
给元素加上$()吧,好了,问题解决了。
在jquery使用中很容易犯这个错误,一定要牢记。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值