代码之家  ›  专栏  ›  技术社区  ›  Josh Bunzel

Node.js PNG缓冲区获取未知图像格式错误

  •  1
  • Josh Bunzel  · 技术社区  · 1 年前

    我正在使用 bwip-js 生成条形码和 pdfkit 以生成将显示所述条形码的pdf。

    我让bwip js生成条形码的png图像,但它只提供png的缓冲区。然后我使用fs.writeFile从缓冲区中生成一个png(这部分可能做得不对)。

    不管怎样,当我把png放在pdf中时,pdfkit会给出一个错误,即图像是 Uknown image format

    同时,如果我在电脑的文件资源管理器中打开保存png的目录,我可以很好地打开图像。

    我发现 this 答案似乎描述了同样的问题,但我并没有运气让bwip js使用生成png。PNG而不是.PNG

    我觉得我在这里缺少了一些东西,比如使用bwip js提供的缓冲区并将其转换为png文件。

    代码:

    const PDFDocument = require("pdfkit");
    const bwipjs = require("bwip-js");
    const fs = require("fs");
    
    function generateCustomerInvoice(data) {
      const id = "12345678"
      bwipjs
        .toBuffer({
          bcid: "code128",
          text: id,
          scale: 3,
          height: 10,
          includetext: true,
          textxalign: "center",
        })
        .then((png) => {
          fs.writeFile("./barcodes/" + id + ".png", png, () => {});
          console.log("Barcode Finished");
        })
        .then(() => {
          const doc = new PDFDocument({ autoFirstPage: false });
          doc.pipe(fs.createWriteStream("./pdfs/customer/" + id + ".pdf"));
          doc.addPage({ size: "A5", margin: 20 });
          doc.lineWidth(1);
          doc.lineCap("butt").moveTo(20, 20).lineTo(399.53, 20).stroke();
          doc.lineCap("butt").moveTo(20, 20).lineTo(20, 575.28).stroke();
          doc.lineCap("butt").moveTo(399.53, 20).lineTo(399.53, 575.28).stroke();
          doc.lineCap("butt").moveTo(20, 575.28).lineTo(399.53, 575.28).stroke();
          doc.fontSize(12).text("Customer Invoice", 40, 40);
          doc.image("./barcodes/" + id + ".png", 40, 40);
          doc.end();
        });
    }
    
    1 回复  |  直到 1 年前
        1
  •  0
  •   Bench Vue    1 年前

    您的书写“.png”图像部分错误。

    Node.js在非阻塞I/O模型上运行,这意味着它不需要等待从文件系统读取或写入文件系统等操作完成后再转到下一行代码。这对性能很有好处,但当一个操作依赖于另一个操作的完成时,可能会导致问题。

    在您的函数中,您使用fs.writeFile()将条形码图像写入磁盘。这种方法是异步的——它开始写入过程,然后立即继续,而不是等待文件写入完成。

    fs.writeFile()函数是异步的。

    这意味着它开始文件写入过程,然后立即转到下一行代码,而无需等待文件写入完成。

    所以下一步“fs.createWriteStream()”没有机会读取完成的图像。 因此,此代码将创建正确的PDF文件。

    const PDFDocument = require("pdfkit");
    const bwipjs = require("bwip-js");
    const fs = require("fs");
    
    function generateCustomerInvoice(invoiceData) {
        const id = invoiceData.invoiceNumber;
        const barcodeDir = "./barcodes/";
        const pdfDir = "./pdfs/customer/";
    
        if (!fs.existsSync(barcodeDir)) {
            fs.mkdirSync(barcodeDir, { recursive: true });
        }
    
        if (!fs.existsSync(pdfDir)) {
            fs.mkdirSync(pdfDir, { recursive: true });
        }
    
        bwipjs.toBuffer({
            bcid: "code128",
            text: id,
            scale: 3,
            height: 10,
            includetext: true,
            textxalign: "center",
        })
            .then((png) => {
                return new Promise((resolve, reject) => {
                    fs.writeFile("./barcodes/" + id + ".png", png, (err) => {
                        if (err) {
                            console.error("Error writing file:", err);
                            reject(err);
                        } else {
                            console.log("Barcode Finished");
                            resolve();
                        }
                    });
                });
            })
            .then(() => {
                const doc = new PDFDocument({ autoFirstPage: false });
                doc.pipe(fs.createWriteStream("./pdfs/customer/" + id + ".pdf"));
                doc.addPage({ size: "A5", margin: 20 });
    
                doc.fontSize(12).text("Customer Invoice", 40, 30);
    
                doc.image("./barcodes/" + id + ".png", 40, 60, { width: 150 });
    
                doc.fontSize(10).text(`Customer Name: ${invoiceData.customerName}`, 40, 130);
    
                const tableTop = 160;
                doc.fontSize(10);
                doc.text("Description", 40, tableTop);
                doc.text("Quantity", 200, tableTop);
                doc.text("Price", 280, tableTop);
                doc.text("Total", 360, tableTop);
    
                let verticalPosition = tableTop;
                invoiceData.items.forEach(item => {
                    verticalPosition += 20;
                    doc.text(item.description, 40, verticalPosition);
                    doc.text(item.quantity, 200, verticalPosition);
                    doc.text(`$${item.price.toFixed(2)}`, 280, verticalPosition);
                    doc.text(`$${(item.quantity * item.price).toFixed(2)}`, 360, verticalPosition);
                });
    
                doc.end();
            })
            .catch((err) => {
                console.error("Error in PDF generation: ", err);
            });
    }
    
    generateCustomerInvoice({
        customerName: "Tom Cruise",
        invoiceNumber: "INV-10001",
        items: [
            { description: "Item 1", quantity: 2, price: 100.00 },
            { description: "Item 2", quantity: 5, price: 50.00 }
        ],
    });
    
    

    后果 enter image description here

    中的更多详细信息 here