如何在 NodeJS 中使用只有 URL 的 Sharp 调整图像大小,使用 async/await,并且没有创建本地副本? [英] How can you resize an image in NodeJS using Sharp having only a URL, using async/await, and without a local copy being created?

查看:81
本文介绍了如何在 NodeJS 中使用只有 URL 的 Sharp 调整图像大小,使用 async/await,并且没有创建本地副本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm working in an environment where the available image processing library is NodeJS's Sharp for scaling images. It has been stable as it is being pipe based, but I'm tasked with converting it into TypeScript, and set it up using Async/Await when possible. I have most of the pieces ready, but the issue I am facing lies in the fact that all I have is a URL of an image and Sharp either expects a string URI (local file only) or a Buffer.

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

Currently, I am using the package Axios in order to fetch the image as a string retrievable by the data property on the response. I've been feeding a buffer created from the string by Buffer.from(response.data) into Sharp, and it doesn't have any issues until I try and "work" with the image by attempting to gather the metadata. At this point it throws an error: [Error: Input buffer contains unsupported image format]. But I know that the image is valid, as it worked in the old system, and I didn't change any dependencies.

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

I use QuokkaJS to test, and the following PoC fails, and I need to get it to functioning order.

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 (这是有道理的).

If anybody has any idea what I am doing incorrectly, or has anything specific information that they would like me to add, please let me know! If I need to pipe the image data, let me know. I've tried to directly pipe it getting a pipe is not a function on the string (which makes sense).

更新 #1:

非常感谢@Thee_Sritabtim 的评论,解决了这个问题.基本上,我一直在尝试将基于流的字符串转换为缓冲区.我需要改为声明请求是针对 ArrayBuffer,然后将其提供给 Sharp,同时声明其类型为 binary.PoC 的工作示例如下!

A big thank you to @Thee_Sritabtim for the comment, which solved the issue. Basically, I had been trying to convert a Stream based String into a Buffer. I needed to instead declare that the request was for an ArrayBuffer, and then feed it into Sharp while declaring its type of binary. The working example of the PoC is below!

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'.

To get a buffer from a axios response, you'll have to set responseType to 'arraybuffer'.

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

或者,

您也可以使用流作为 sharp() 的输入,这样您就可以将 responseType 保留为 'stream'

You could also use stream as input for sharp(), so you could keep the responseType to 'stream'

const imageResponse = await axios({url: url, responseType: 'stream'})

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

这篇关于如何在 NodeJS 中使用只有 URL 的 Sharp 调整图像大小,使用 async/await,并且没有创建本地副本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆