js使用canvas拼接图片

js 同时被 2 个专栏收录
2 篇文章 0 订阅
2 篇文章 0 订阅

人狠话不多,先看看图,是不是你需要的效果(文章最后有最终效果),样子有点点那个啥,将就着看一下就是了(图片来自网络):

测试代码如下

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
    <div class="img-boxs">
        图片一
        <img crossOrigin="Anonymous" src="http://cdn2.jianshu.io/assets/default_avatar/8-a356878e44b45ab268a3b0bbaaadeeb7.jpg" width="300"   class="merging" alt="">
        图片二
        <img crossOrigin="Anonymous" src="https://t12.baidu.com/it/u=1341260975,315835678&fm=76" width="100" class="merging" alt="">
        <p>canvas拼接</p>
        <canvas id="canvas"></canvas>
    </div>
    <button id="btn-merge">拼接</button>
    <button id="save">保存</button>
</body>
<script>
    $(function () {
        var l_src = '';
        var $imgs = $('.img-boxs .merging'),
            $btnMerge = $('#btn-merge'),
            srcs = [],
            arr_img_w = [],
            arr_img_h = [],
            imgs_num = $imgs.length,
            loaded_img = 0;
        var loading = function () {
            console.log(imgs_num);
            for (let i = 0; i < imgs_num; i++) {
                try{
                    if (!$($imgs[i])) {
                        throw 'loading函数参数$imgs['+i+']不能为空';
                    }
                    srcs[i] = $($imgs[i]).attr("src");
                    let _image = new Image();
                    _image.onload = function(){
                        arr_img_w[i] = (_image.width);
                        arr_img_h[i] = (_image.height);
                    };
                    _image.src = srcs[i];
                    //保存图片的原始宽高
                    //不论图片加载完成还是失败都执行该函数
                    $(_image).on('load error', function () {
                        loadImage();
                    });

                } catch (err) {
                    alert("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();
        });
        $("#save").on('click', function () {
            if(l_src){
                var dlLink = document.createElement('a');
                dlLink.download = "文件名.png";
                dlLink.href = l_src;
                dlLink.click();
            }else{
                alert("请先生成文件")
            }

        });
        function mergeImages () {
            try {
                if (loaded_img!==imgs_num && 2!==imgs_num) {
                    throw '图片未加载完成或图片的数目不为2';
                    return false;
                }
                var canvas = document.querySelector("#canvas"),
                    temp_w = 0,
                    temp_h = 0,
                    ctx = {};
                canvas.width = getMaxofArray(arr_img_w);
                canvas.height = getMaxofArray(arr_img_h);
                console.log("width",arr_img_w,arr_img_h,canvas.width,canvas.height);
                ctx = canvas.getContext('2d');
                for (let i = 0; i < imgs_num; i++) {
                    temp_w = arr_img_w[i];
                    temp_h = arr_img_h[i];
                    if (i == (imgs_num-1)) {
                        console.log("...",canvas.width,temp_w);
                        ctx.drawImage($imgs[i], 0, 0, temp_w, temp_h, canvas.width-temp_w, canvas.height-temp_h, temp_w, temp_h);
                    } else {
                        ctx.drawImage($imgs[i], 0,0,canvas.width,canvas.height,0,0,canvas.width,canvas.height);
                    }
                }
                l_src = canvas.toDataURL('image/png');
            } catch (err) {
                printError(err);
            }
        }
        function getMaxofArray (elems) {
            try {
                if (!Array.isArray(elems)) {
                    throw 'getMaxofArray函数的参数必须是数组';
                }
            } catch (err) {
                printError(err);
            }
            return Math.max.apply(null, elems);
        }
        function printError (msg) {
            console.log('error message:', msg);
        }
    });
</script>
</html>

注意点:

crossOrigin属性必须在src之前

图片加载完成的先后顺序不一定,所以代码中没有使用push,而是

_image.onload = function(){
  arr_img_w[i] = (_image.width);
  arr_img_h[i] = (_image.height);
};

 以上的代码还存在一个问题,如果需要自动生成,而不是点击的话,需要判断图片是否加载完成

完整代码如下

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>蜀创助贷</title>
    <script src="./js/jquery.min.js"></script>
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="box" id="outer">
    <img src="./img/bg.png" id="merge" width="100%" alt="">
    <div class="alert none" id="centerBox">
        <img src="#" id="head" width="200" alt="头像">
        <h3>长按保存头像</h3>
    </div>
</div>
</body>
<script>
    $(function () {
        let $_REQUEST = new Object, aParams = document.location.search.substr(1).split("&");
        for (let i = 0; i < aParams.length; i++) {
            let aParam = aParams[i].split("=");
            $_REQUEST[aParam[0]] = aParam[1]
        }
        let srcs=["./img/bg.png","./img/logo.png",$_REQUEST["img"]];
        let imgDom=[];
        let arr_img_w=[];
        let arr_img_h=[];
        $("#outer").on('click', function () {
            let canvas2 = document.createElement("canvas");
            let ctx = {};
            canvas2.width = 1000;
            canvas2.height = 1000;
            ctx = canvas2.getContext('2d');
            ctx.drawImage(imgDom[2], 0,0,1000,1000);
            ctx.drawImage(imgDom[1], 0,0,1000,1000);
            let l_src = canvas2.toDataURL('image/png');
            $("#head").attr('src', l_src);
            $("#centerBox").toggleClass("none")
        });

        $("#btn-merge").on('click', function () {
            mergeImages();
        });
//        var loading = function () {
//            for (let i = 0; i < srcs.length; i++) {
//                try{
//                    let _image = new Image();
//                    _image.onload = function(){
//                        arr_img_w[i] = (_image.width);
//                        arr_img_h[i] = (_image.height);
//                    };
//                    _image.crossOrigin = "Anonymous";
//                    _image.src = srcs[i];
//                    imgDom.push(_image);
//
//                } catch (err) {
//                    alert("err");
//                }
//            }
//        };
//
//        function getMaxofArray (elems) {
//            try {
//                if (!Array.isArray(elems)) {
//                    throw 'getMaxofArray函数的参数必须是数组';
//                }
//            } catch (err) {
//                alert(err)
//            }
//            return Math.max.apply(null, elems);
//        }

        function mergeImages () {
            try {
                let canvas = document.createElement("canvas");
                let temp_w = 0;
                let temp_h = 0;
                let ctx = {};
                canvas.width = 640;
                canvas.height = 1008;
                ctx = canvas.getContext('2d');
                ctx.drawImage(imgDom[0], 0,0,640,1008,0,0,640,1008);
                ctx.drawImage(imgDom[2], 0,0,arr_img_w[2],arr_img_w[2],185,505,290,290);
                ctx.drawImage(imgDom[1], 0,0,arr_img_w[1],arr_img_h[1],180,500,300,300);
                let l_src = canvas.toDataURL('image/png');
                $("#merge").attr('src', l_src);
            } catch (err) {
                alert(err)
            }
        }
        function loadImg(url,i, cb) {
            let _image = new Image();
            _image.onload = function(){
                arr_img_w[i] = (_image.width);
                arr_img_h[i] = (_image.height);
                imgDom[i] = _image;
                cb();
            };
            _image.crossOrigin = "Anonymous";
            _image.src = srcs[i];
        }

        function loadImages(urlArr, afterAllLoadedFunc) {
            var count = urlArr.length;
            var loadedCount = 0;

            for (var i = count - 1; i >= 0; i--) {
                loadImg(urlArr[i],i, function () {
                    loadedCount ++;
                    if (count === loadedCount) {
                        afterAllLoadedFunc();
                    }
                });
            }
        }
        
        loadImages(srcs, function () {
            mergeImages()
        });
    })
</script>
</html>

看效果图

拼接前的图片:加上自己的头像

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

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

抵扣说明:

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

余额充值