前端实现:背景可编辑,批量生成带背景的二维码海报图片(一)

131 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

功能:纯前端实现:背景可更改,大小可自定义,支持导入二维码链接txt文件,转换二维码为图片,生产合并后的图片,实现图片的批量打包下载。 分析:

  • 本地图片上传
  • 图片合并
  • 生成图片保存
  • txt 文件读取
  • 文件批量生成
  • 文件打包下载
  • 二维码图片中间添加logo

本地图片上传

使用input ,type="file"实现本地图片的读取功能,如果需要上传至服务器,代码中使用form表单上传,可根据需要自行更改 html

<div class="select-btn">
    <span>上传背景图片</span>
    <form id="viaBox" method="post" enctype="multipart/form-data">
        <input name="file" id="upImg" type="file" accept />
    </form>
</div>
<!-- 图片展示区域 -->
<div class="img-box">
    <img class="img" id="bgImg" />
    <div id="code"></div>
</div>

js

    // 背景图片
    var bgImage = "";
    $("#upImg").change(function (e) {
        var _URL = window.URL || window.webkitURL;
        var file, img;
        // 本地图片
        if ((file = this.files[0])) {
            img = new Image();
            img.onload = function () {
                $(".img").attr("src", this.src);
            };
            img.src = _URL.createObjectURL(file);
            bgImage = img;
        }
        return;
        // 如果不需要上传执行到这里就可以了
        if ((file = this.files[0])) {
            $.ajax({
                type: "post",
                url: baseUrl,
                cache: false, //上传数据不需要缓存
                contentType: false, //已经在表单的entype处声明了multipart/form-data
                processData: false, //data值是FormData对象,不需要对数据做处理
                data: new FormData($("#viaBox")[0]),
                success: function (res) {
                    console.log(res.url);
                    img = new Image();
                    img.onload = function () {
                        $(".img").attr("src", this.src);
                    };
                    img.src = res.url;
                    bgImage = img;
                },
                error: function (err) {
                    alert("上传图片出错");
                },
            });
        }
    });

image.png

图片合并

有了背景图,实现两张图片的合并,需要用canvas进行绘制,此处没有使用html2canvans插件,因为html2canvas是对页面显示的内容转换成图片保存,本次希望实现的批量保存的效果,大部分转换的图片不会在页面上展示,没有展示的使用插件生成的空白,所有本次不用。直接生成单张海报,用该插件还是比较方便的。

 function draw(imgItem) {
        var c = document.createElement("canvas"),
            ctx = c.getContext("2d");
        c.width = Number($("#bgW").val()) * dpr;
        c.height = Number($("#bgH").val()) * dpr;
        ctx.rect(0, 0, c.width, c.height);
        ctx.fillStyle = "#fff";
        ctx.fill();
        ctx.drawImage(bgImage, 0, 0, c.width, c.height);
        var img = new Image();
        img.src = imgItem.url;
        img.crossOrigin = "Anonymous"; //解决跨域
        // 测试时,加载本地图片 img.onload 不调用,采用下面写法可正常
        img.addEventListener(
            "load",
            function () {
                console.log("add--load");
                ctx.drawImage(
                    img,
                    0,0,150,150
                );
                $("#mergeImg").attr("src", c.toDataURL("image/jpeg", 1));
            },
            false
        );
        // img.οnlοad = function () {
        //     console.log("onload");
        //     ctx.drawImage(img, 0, 0, c.width, c.height);
        // };
    }

图片转换成base64保存

``

// 得到的就是base64格式的字符串
var base64 = c.toDataURL("image/jpeg", 1)

base64 转换成图片保存

    function saveImage() {
        if (base64) {
            // 含"data:image/png;base64," 需要自己做截取处理
            var raw = window.atob(base64.split(",")[1]);
            var rawLength = raw.length;
            var uInt8Array = new Uint8Array(rawLength);
            for (var i = 0; i < rawLength; ++i) {
                uInt8Array[i] = raw.charCodeAt(i);
            }
            var blob = new Blob([uInt8Array], {
                type: "image/jpeg",
            });
            //保存图片
            var aLink = document.createElement("a");
            var evt = document.createEvent("HTMLEvents");
            evt.initEvent("click", true, true);
            aLink.download = fileName;
            aLink.href = URL.createObjectURL(blob);
            aLink.click();
        } else {
            console.log("没有base64代码");
        }
    }

今天暂时到这里,后面继续~~