【问题标题】:azure function to convert pdf to image in node.js?在node.js中将pdf转换为图像的天蓝色函数?
【发布时间】:2020-08-28 04:29:19
【问题描述】:

我正在尝试编写一个 Azure 函数来将 pdf 转换为 Node.js 中的图像,但没有成功。直接在 azure 门户中编写。使用开箱即用的 pdf-poppler 包。这里 sourcepdf 和 targetimage 是我的 blob 容器。

下面是代码,

const pdf = require('pdf-poppler');
const path = require('path');
const fs = require('fs');
const URL = require('url');


const storage = require('azure-storage');


module.exports = async function (context, myBlob) {

context.log(context.bindingData.blobTrigger);
//context.log(context.bindingData.uri);
let file = '/sourcepdf/sample.pdf';

let opts = {
    format: 'jpeg',
    out_dir: '/targetimage/sample.jpg',
    out_prefix: path.baseName(file, path.extname(file)),
    page: null
}
pdf.convert(file, opts)
    .then(res => {
        console.log('Successfully converted');
    })
    .catch(error => {
        console.error(error);
    })

    //context.log("JavaScript blob trigger function processed blob \n Blob:",  context.bindingData.blobTrigger, "\n Blob Size:", myBlob.length, "Bytes");     

};

任何建议,

【问题讨论】:

  • 控制台记录了什么错误?是不是找不到文件?
  • 我不认为您可以像这样编写文件系统路径并假设它们会自动映射到 Azure blob 存储容器。 pdf-poppler 可以处理文件流还是需要磁盘上的文件?我猜您必须将源文件从 blob 存储中传输出来,对其进行处理,然后再次将其上传回来,但我不知道临时本地文件如何与 Azure 函数一起使用。
  • 我得到的错误是,异常:TypeError: path.baseName is not a function
  • 哦,对了:basename 全部小写。但如上所述,我不认为这些路径实际上只适用于 blob 存储,而不需要做一些额外的工作来显式地传入和传出文件。

标签: javascript azure azure-functions azure-blob-storage


【解决方案1】:

以下是我的工作代码:

context.log('JavaScript HTTP trigger function processed a request.');
    let file = 'D:\\home\\site\\wwwroot\\nodejs.pdf'

    let opts = {
        format: 'jpeg',
        out_dir: path.dirname(file),
        out_prefix: path.basename(file, path.extname(file)),
        page: null
    }

    pdf.convert(file, opts)
        .then(res => {
            console.log('Successfully converted');
        })
        .catch(error => {
            console.error(error);
        })

除此之外,您可以定义输出目录和文件名前缀,例如out_dir 可以是context.executionContext.functionDirectory,而out_prefix 只是像output 这样的字符串。它将在函数文件夹下创建图像。

【讨论】:

  • await uploadLocalFile(aborter, destcontainerClient, path.join(tarDir, file));
  • 嗨乔治,这正在工作,现在我得到了我正在尝试将转换后的文件上传到 azure blob 的文件。但是要将文件上传到 blob,它必须使用 async-await。上述转换过程正在返回一个承诺。那么我们如何在 Promise 中编写 async-await。 return new Promise((resolve, reject) => { pdf .convert(sourceDirectory, opts) . then((response) => { await uploadLocalFile( aborter, destcontainerClient, path.join(tarDir, file) );
  • 嗨@user3432478 你是如何在天蓝色功能上做到这一点的?
【解决方案2】:

您在赏金中提到您正在寻找一个直接上传到 blob 存储并使用 async/await 的函数。

要直接上传到 blob 存储,您需要在函数中添加 blob storage output binding

您的function.json 文件将如下所示:

{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    },
    {
      "type": "blob",
      "direction": "out",
      "name": "outBlob",
      "path": "my-container/{rand-guid}.jpg",
      "connection": "AzureWebJobsStorage"
    }
  ]
}

此输出绑定将在函数中以context.bindings.outBlob 的形式提供;

要让 JavaScript 中的同步方法可等待,我们可以使用 util.promisify 函数 as is recommended by Microsoft in this example

最后,为了满足我们需要使用fs 将文件读取到内存的要求,因为pdf-poppler 库不支持将文件保存到内存,始终将函数的输出保存在磁盘上。

我创建了一个示例 Azure 函数,它采用 HTTP POST 触发器,将单页 PDF 处理为图像并将其保存到 Azure Blob 存储。

const fs = require("fs");
const fsPromises = require("fs/promises");
const util = require("util");
const pdf = require("pdf-poppler");
const os = require("os");
const path = require("path");

// Use async/await pattern as recommended by Microsoft:
// https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=v2#use-async-and-await
const readFileAsync = util.promisify(fs.readFile);
const writeFileAsync = util.promisify(fs.writeFile);

// Trigger this function with a HTTP POST with a PDF file encoded via form-data
module.exports = async function (context, req) {
    context.log("JavaScript HTTP trigger function is processing a request.");

    if (!req.body) {
        return { status: 400, body: "No PDF file was provided!" };
    }

    // Create temp directory
    const tempPath = await fsPromises.mkdtemp(os.tmpdir() + path.sep);
    const pdfLocation = path.join(tempPath, "my-pdf.pdf");

    // Save HTTP body for further processing
    await writeFileAsync(pdfLocation, req.body, "binary");

    // Convert PDF to JPEG
    await pdf.convert(pdfLocation, {
        format: "jpg",
        out_dir: tempPath,
        out_prefix: "my-image",
        page: 1
    });

    // Read local file into memory and set as output binding
    context.bindings.outBlob = await readFileAsync(path.join(tempPath, "my-image-1.jpg"));

    return {
        status: 200,
        body: "Your PDF file has been converted to a JPEG file and uploaded to Azure Blob Storage."
    };
}

确保在部署到 Azure Functions 应用时使用 Web 部署,或者将环境变量 WEBSITE_RUN_FROM_PACKAGE 设置为 0Otherwise, your file system will be read-only 函数会失败!

能够处理多页 PDF 是一项留给读者的练习。

【讨论】:

    猜你喜欢
    • 2023-04-02
    • 2017-01-05
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    相关资源
    最近更新 更多