async function imgResize(data){
// Convert base64 to buffer => <Buffer ff d8 ff db 00 43 00 ...
const buffer = Buffer.from(data, "base64");
Jimp.read(buffer, (err, res) => {
if (err) throw new Error(err);
console.log("Original image size: "+res.getWidth()+"x"+res.getHeight())
if (res.getWidth() > 1025){
res.resize(1025, Jimp.AUTO)
console.log("resized image size: "+res.getWidth()+"x"+res.getHeight())
}
res.getBase64(Jimp.AUTO, (err, value)=>{
if(err){return err)}
return value;
})
}
const img = await imgResize(base64data)
I get, SyntaxError: await is only valid in async functions and the top level bodies of modules. But if I remove the async and just print the value without returning it, it works fine. So how I will able to get the value out of that function as return value and hold it in a variable?
You can't return values inside an asynchronous callback and expect them to be assigned to a variable. Asynchronous callbacks are executed at a later point in time by Node.js at which point the execution context is lost. For example, this won't work:
function getImageWidth(buffer) {
Jimp.read(buffer, (err, res) => {
// Outside context is lost and returning here doesn't
// affect the return value of `getImageWidth` parent function
return res.getWidth(); // won't work 🚫
}
}
const width = getImageWidth(buffer);
console.log(width); // undefined
To accomplish what you want, you have two options:
Turns out Jimp returns a promise if you don't pass a callback function so going for solution #1 is most straightforward. Refactoring from callbacks to async/await would give us the following:
async function imgResize(data) {
const buffer = Buffer.from(data, "base64");
const res = await Jimp.read(buffer);
console.log(`Original image size: ${res.getWidth()} x ${res.getHeight()}`);
if (res.getWidth() > 1025){
res.resize(1025, Jimp.AUTO);
console.log(`Resized image size: ${res.getWidth()} x ${res.getHeight()}`);
}
return res.getBase64Async(Jimp.AUTO);
}
const img = await imgResize(base64data);
Note: For this to work you need to have top-level await enabled by using ES Modules (ESM). Otherwise you should wrap the last line in an IIFE:
(async () => {
const img = await imgResize(base64data);
)();