Reputation: 78
I am trying to fetch the image from a remote url, resize it and save it to my computer locally. For this, i am using got library which returns a buffer. i take that buffer and resize the image and then store it in a file using sharp js. Here is my code:
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";
}
The console.log(storedValue)
gives:
{
format: 'jpeg',
width: 200,
height: 200,
channels: 3,
premultiplied: false,
size: 5432
}
However, the output image is not shown as a jpeg by my windows machine.
It shows like this:
The filename output is the output from the code above. hacker is a random unused jpg image. specifying output.jpg to the file does give me a jpg image but the input can be any format jpg, png, gif so, i need to have the same extension as the media.
Upvotes: 1
Views: 1396
Reputation: 4421
Sharp generates the image without an extension because you don't supply one. The first argument for toFile
is fileOut
, which represents the path to write the image data to. Since the string "output" doesn't have an extension specified, the image is generated without an extension as that is what we tell it to do.
If you utilize the format
parameter of your user defined resize
function, then you can supply a media extension in the function calls and the generated images will have the expected extension types.
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
Or if you choose to not define a format
parameter for the resize
function, you can grab the image extension from the resizedBuffer
. I looked through the output and found options
contains a key tiffCompression
which defines the media extension type that Sharp received from the 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)
Upvotes: 1