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

75 阅读1分钟

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

读取txt文件

txt 文件的格式:(如果没有图片名称,会使用日期+索引值作为文件名称)

链接,图片名称

示例:

https://www.baidu.com?a=1,pic1
https://www.baidu.com?a=2,pic2
https://www.baidu.com?a=3,pic3
https://www.baidu.com?a=4,pic4

image.png

链接,文件名称

<div class="select-btn">
    <span>读取txt文件</span>
    <input type="file" name="file" multiple="multiple" id="readTxt" />
</div>
$("#readTxt").change(function (e) {
    codeList = [];
    var fileList = document.getElementById("readTxt").files;
    var nameStr = "";
    for (var i = 0; i < fileList.length; i++) {
        nameStr += `${i === 0 ? "" : ", "}${fileList[i].name}`;
        var reader = new FileReader();
        reader.readAsText(fileList[i], "UTF-8");
        reader.onload = function (e) {
            var content = e.target.result;
            // console.log(content);
            var arr = content.split("\n");
            var txtHtml = "<ul>";
            for (let i = 0; i < arr.length; i++) {
                var iList = arr[i].split(",");
                var name =
                    iList[1] ??
                    new Date().Format("yyyyMMddhhmmss") + "-" + i;
                codeList.push({
                    url: iList[0],
                    name: name,
                });
                txtHtml += "<li>" + iList[0] + "     " + name + "</li>";
            }
            txtHtml += "</ul>";
            console.log(codeList);
            document.getElementById("text").innerHTML = txtHtml;
        };
    }
    document.getElementById("name").append(nameStr);
});

链接转二维码

不带logo版本

需要引入的JQuery库:jquery.min.js、jquery.qrcode.min.js

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery.qrcode/1.0/jquery.qrcode.min.js"></script>

<div id="code"></div>
<script>
//url中带中文,需要转UTF-8
function toUtf8(str) {
        var out, i, len, c;
        out = "";
        len = str.length;
        for (i = 0; i < len; i++) {
                c = str.charCodeAt(i);
                if ((c >= 0x0001) && (c <= 0x007F)) {
                        out += str.charAt(i);
                } else if (c > 0x07FF) {
                        out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
                        out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
                        out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
                } else {
                        out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
                        out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
                }
        }
        return out;
}
// 设置二维码参数
jQuery(function() {
        $('#code').qrcode({
                render: "canvas",
                width: 200, 
                height: 200, 
                background: "#FFFFFF", // 背景颜色
                foreground: "#000000", // 前景颜色
                correctLevel: 0, // 纠错等级 
                src: 'images/logo4.png',
                text: toUtf8("jQury二维码生成插件") // 任意内容
        });
})
</script>

带logo版本

QrCodeWithLogo 使用方法:

<script src="https://unpkg.com/qr-code-with-logo@1.1.0/lib/qr-code-with-logo.browser.min.js"></script>

QrCodeWithLogo.toCanvas({
    canvas: tempCanvas,
    content'https://www.baidu.com',
    width510,
    logo: {
      // 二维码中的logo 图片
      src'/assets/logo.png',
      borderRadius10,
      borderSize : 0
    }
})

合并

上面已经完成了图片链接转二维码和txt文件的读取,下面就是需要将读到的内容,一次生成图片,并将base64数据保存在数组list中,最后将list中的数据批量打包下载。

// url需要装换成二维码后绘制
var tempCanvas = document.createElement("canvas");
QrCodeWithLogo.toCanvas({
    canvas: tempCanvas,
    content: imgItem.url,
    width: Number($("#codeW").val()),
    logo: {
        src:
            "img/logo.png,
        crossOrigin: "Anonymous",
        borderRadius: 10,
        borderSize: 0,
    },
}).then(function () {
    // 此处添加定时器,否则生产带logo的图片过程中,部分logo没有绘制在图片上
    setTimeout(function () {
        var c = document.createElement("canvas"),
            ctx = c.getContext("2d");
        c.width = Number($("#bgW").val());
        c.height = Number($("#bgH").val());
        ctx.rect(0, 0, c.width, c.height);
        ctx.fillStyle = "#fff";
        ctx.fill();
        ctx.drawImage(bgImage, 0, 0, c.width, c.height);
        // 绘制二维码Canvas
        ctx.drawImage(
            tempCanvas,
            Number($("#codeT").val()),
            Number($("#codeL").val()),
            Number($("#codeW").val()),
            Number($("#codeH").val())
        );
        let data = c.toDataURL("image/jpeg", 1);
        base64.push({
            content: c.toDataURL("image/jpeg", 1),
            name: imgItem.name,
        });
        // 调试过程,将生成的图片都append在页面上,方便查看效果
        $("#area").append(`<img width="200" src="${data}"/>`);
    }, 500);
});

带logo的多张图片生成的时候,需要使用定时器延时:添加定时器,否则生产带logo的图片过程中,部分logo没有绘制在图片上

image.png for循环上面方法,一次生成带二维码的图片,base64数组,后面导出压缩包使用 image.png

生成zip包

jszip仓库:github.com/Stuk/jszip/…

$("#downloadZip").click(function () {
    var zip = new JSZip();
    for (let i = 0; i < base64.length; i++) {
        zip.file(base64[i].name + ".jpg", base64[i].content.split(",")[1], {
            base64: true,
        });
    }
    // 生成zip文件并下载
    zip.generateAsync({
        type: "blob",
    }).then(function (content) {
        // 下载的文件名
        var filename = new Date().Format("yyyyMMddhhmmss") + "-gen.zip";
        // 创建隐藏的可下载链接
        var eleLink = document.createElement("a");
        eleLink.download = filename;
        eleLink.style.display = "none";
        // 下载内容转变成blob地址
        eleLink.href = URL.createObjectURL(content);
        // 触发点击
        document.body.appendChild(eleLink);
        eleLink.click();
        // 然后移除
        document.body.removeChild(eleLink);
    });
});