在 nodejs 中使用 sharp 保存的媒体文件具有不受支持的类型

Saved Media file has unsupported type using sharp in nodejs

我正在尝试从远程 url 获取图像,调整其大小并将其保存到本地计算机。为此,我正在使用 returns 缓冲区的 got 库。我获取该缓冲区并调整图像大小,然后使用 sharp js 将其存储在文件中。这是我的代码:

module.exports =  async function resize() {
    const url = 'https://images.unsplash.com/photo-1636838123974-c94c6904b97a?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=687&q=80';

const readStream = await got(url).buffer();
const resizedBuffer = await sharp(readStream).resize(200, 200);
const storedValue = await resizedBuffer.toFile('output');
console.log("resized buffer", resizedBuffer);
console.log("-----------------------------------------------------------")
console.log(storedValue);
return "ok";

}

console.log(storedValue) 给出:

{
  format: 'jpeg',
  width: 200,
  height: 200,
  channels: 3,
  premultiplied: false,
  size: 5432
}

但是,我的 windows 机器没有将输出图像显示为 jpeg。 显示如下:

文件名输出是上面代码的输出。黑客是一个随机未使用的 jpg 图像。为文件指定 output.jpg 确实给我一张 jpg 图像,但输入可以是任何格式的 jpg、png、gif 所以,我需要与媒体具有相同的扩展名。

Sharp 生成没有扩展名的图像,因为您没有提供扩展名。 toFile 的第一个参数是 fileOut,代表写入图像数据的路径。由于字符串“output”没有指定扩展名,因此生成的图像没有扩展名,因为这是我们告诉它要做的。

如果您使用用户定义的 resize 函数的 format 参数,那么您可以在函数调用中提供媒体扩展,生成的图像将具有预期的扩展类型。

const BASE_URL = "https://images.unsplash.com/";
const imgUrl = "photo-1636838123974-c94c6904b97a?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=687&q=80";
const fullUrl = `${BASE_URL}${imgUrl}`;

async function resize(url, format, width, height, filename) {
    const readStream = await got(url).buffer();
    const resizedBuffer = await sharp(readStream).resize(width, height);
    const storedValue = await resizedBuffer.toFile(`${filename}.${format}`);
    console.log("resized buffer", resizedBuffer);
    console.log("-----------------------------------------------------------")
    console.log(storedValue);
    return "ok";
}

resize(fullUrl, "png", 200, 200, "foo");
// generates foo.png (image of 3 croissants on a plate)

resize(fullUrl, "jpg", 200, 200, "bar");
// generates bar.jpeg

或者如果您选择不为 resize 函数定义 format 参数,您可以从 resizedBuffer 中获取图像扩展名。我查看了输出,发现 options 包含一个键 tiffCompression,它定义了 Sharp 从 readStream.

接收到的媒体扩展类型

const BASE_URL = "https://images.unsplash.com/";
const imgUrl = "photo-1636838123974-c94c6904b97a?ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&ixlib=rb-1.2.1&auto=format&fit=crop&w=687&q=80";
const fullUrl = `${BASE_URL}${imgUrl}`;

async function resize(url, width, height, filename) {
    const readStream = await got(url).buffer();
    const resizedBuffer = await sharp(readStream).resize(width, height);
    const format = resizedBuffer["options"]["tiffCompression"];
    const storedValue = await resizedBuffer.toFile(`${filename}.${format}`);
    console.log("resized buffer", resizedBuffer);
    console.log("-----------------------------------------------------------")
    console.log(storedValue);
    return "ok";
}

resize(fullUrl, 200, 200, "foo");
// generates foo.jpeg (image of 3 croissants on a plate)