node.js - 如何在 NodeJS 中使用只有 URL 的 Sharp 调整图像大小,使用 async/await,并且没有创建本地副本?

标签 node.js typescript axios sharp

我在一个环境中工作,其中可用的图像处理库是 NodeJS 的 Sharp用于缩放图像。它一直很稳定,因为它是基于管道的,但我的任务是将它转换为 TypeScript,并在可能的情况下使用 Async/Await 进行设置。我已准备好大部分内容,但我面临的问题在于,我所拥有的只是图像的 URL,而 Sharp 需要字符串 URI(仅限本地文件)或缓冲区。

目前,我正在使用包 Axios为了将图像作为可由 data 检索的字符串获取响应的属性。我一直在提供由 Buffer.from(response.data) 从字符串创建的缓冲区进入 Sharp,它没有任何问题,直到我尝试通过尝试收集元数据来“处理”图像。此时它抛出一个错误:[Error: Input buffer contains unsupported image format] .但我知道该镜像是有效的,因为它在旧系统中有效,而且我没有更改任何依赖项。

我使用 QuokkaJS 进行测试,以下 PoC 失败,我需要使其正常运行。

import axios from 'axios';
import Sharp from 'sharp';
const url = 'https://dqktdb1dhykn6.cloudfront.net/357882-TLRKytH3h.jpg';

const imageResponse = await axios({url: url, responseType: 'stream'});
const buffer = Buffer.from(imageResponse.data);
let src = new Sharp(buffer);
const src2 = src.clone();//this is simply because it will end up being a loop, if this is the issue let me know.
try {
    await src2.jpeg();
    await src2.resize(null, 1920);
    await src2.resize(1080, null);
    const metadata = await src2.clone().metadata();//this is where it fails
    console.log(metadata);
} catch(e) {
    console.log(e);//logs the mentioned error
}

如果有人知道我做错了什么,或者有任何他们希望我添加的具体信息,请告诉我!如果我 需要要通过管道传输图像数据,请告诉我。我试图直接通过管道获取 pipe is not a function在字符串上(这是有道理的)。

更新 #1:

非常感谢@Thee_Sritabtim 的评论,解决了这个问题。基本上,我一直在尝试将基于流的字符串转换为缓冲区。我需要改为声明该请求是针对 ArrayBuffer 的。 ,然后将其输入 Sharp,同时声明其类型为 binary . PoC 的工作示例如下!
import axios from 'axios';
import Sharp from 'sharp';
const url = 'https://dqktdb1dhykn6.cloudfront.net/357882-TLRKytH3h.jpg';

const imageResponse = await axios({url: url, responseType: 'arraybuffer'});
const buffer = Buffer.from(imageResponse.data, 'binary');
let src = new Sharp(buffer);
try {
    await src.jpeg();
    await src.resize(null, 1920);
    await src.resize(1080, null);
    const metadata = await src.metadata();//this was where it failed, but now it prints an object of metadata
    console.log(metadata);
} catch(e) {
    console.log(e);//Doesn't catch anything any more!
}

最佳答案

axios 获取缓冲区响应,您必须设置 responseType'arraybuffer' .

const imageResponse = await axios({url: url, responseType: 'arraybuffer'})
const buffer = Buffer.from(imageResponse.data, 'binary')

或者,

您也可以使用流作为 sharp() 的输入,因此您可以保留 responseType'stream'
const imageResponse = await axios({url: url, responseType: 'stream'})

const src = imageResponse.data.pipe(sharp())
//...
const metadata = await src.metadata()

关于node.js - 如何在 NodeJS 中使用只有 URL 的 Sharp 调整图像大小,使用 async/await,并且没有创建本地副本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61778606/

相关文章:

node.js - typescript: tsc 不是内部或外部命令,也不是可运行的程序 或批处理文件

node.js - npm启动后返回Cmder提示符

javascript - 使用 Node/JS 合并两个数据集

javascript - 删除列表项的选项

character-encoding - Axios 的编码问题

node.js - 在重定向时发送错误消息

angular - 错误类型错误 : Cannot assign to read only property 'isSelected' of object '[object Object]'

javascript - 在 Angular 4 中 Plotly 找不到带有 ngIf 的 HTML 元素

javascript - 如何在Vue Js中通过axios调出查询

javascript - Django 休息框架 : HTTP 401 Unauthorized error