I am calling sharp(tmpFilePath).resize(150, 150).toFile(resizedFilePath) but the output file that's being produced is showing as type application/octet-stream rather than an image/jpeg, which is the original file type. I am using Angular and downloading/uploading to Firebase storage via cloud functions. When I download the source file and upload it right back to Firebase without calling the sharp API first, the newly uploaded file is an image/jpeg file, so I am pretty sure it's something I am doing incorrectly with the Sharp api. Thanks in advance for any assistance.
Original file:

File returned by Sharp API:

My function from index.ts:
export const resizeImages = functions.storage.object().onFinalize(async object => {
try {
console.log(object);
const bucket = admin.storage().bucket(object.bucket);
const filePath = object.name;
const fileName:string = filePath.split('/').pop();
const bucketDir = dirname(filePath);
console.log("filePath: " + filePath + "; fileName: " + fileName + "; bucketDir: " + bucketDir);
if (bucketDir === 'profile-image' && object.contentType.includes('image')){
console.log("A profile picture was added...")
//The file is a profile picture...
if (fileName.includes('unsized@')) {
console.log("The picture that was added hasn't been sized yet...")
//The file needs to be resized...
const workingDir = join(tmpdir(), 'thumbs');
const tmpFilePath = join(workingDir, fileName);
// 1. Ensure thumbnail dir exists
await fs.ensureDir(workingDir);
// 2. Download Source File
await bucket.file(filePath).download({
destination: tmpFilePath
});
console.log("Downloaded the source file");
console.log(tmpFilePath);
// 3. Resize the image ********THIS PART IS NOT HAPPENING CORRECTLY
console.log("About to start resizing...");
const resizedfileName: string = fileName.split('@').pop();
const resizedFilePath = join(workingDir, resizedfileName);
await sharp(tmpFilePath).resize(150, 150).toFile(resizedFilePath);
console.log("The image resizing is complete: "+ resizedFilePath);
// 4. Upload the resized image
const resizedImageUploadSnapshot = await bucket.upload(resizedFilePath, {destination: join('profile-image', resizedfileName)});
console.log("Uploaded the resized image ");
// 5. Cleanup remove the tmp/thumbs from the filesystem
await fs.remove(workingDir);
console.log("FUNCTION COMPLETED SUCCESSFULLY!")
return true;
} else {
return false;
}
} else {
console.log('exiting function');
return false;
}
} catch (error) {
console.log(error);
return error;
}
Hello, sorry, this question relates to things well beyond the realms of sharp so perhaps a site like StackOverflow might be a better place to ask this.
I am calling
sharp(tmpFilePath).resize(150, 150).toFile(resizedFilePath)but the output file that's being produced is showing as typeapplication/octet-streamrather than animage/jpeg, which is the original file type. I am using Angular and downloading/uploading to Firebase storage via cloud functions. When I download the source file and upload it right back to Firebase without calling the sharp API first, the newly uploaded file is animage/jpegfile, so I am pretty sure it's something I am doing incorrectly with the Sharp api. Thanks in advance for any assistance.Original file:
File returned by Sharp API:
My function from index.ts:
export const resizeImages = functions.storage.object().onFinalize(async object => { try { console.log(object); const bucket = admin.storage().bucket(object.bucket); const filePath = object.name; const fileName:string = filePath.split('/').pop(); const bucketDir = dirname(filePath); console.log("filePath: " + filePath + "; fileName: " + fileName + "; bucketDir: " + bucketDir); if (bucketDir === 'profile-image' && object.contentType.includes('image')){ console.log("A profile picture was added...") //The file is a profile picture... if (fileName.includes('unsized@')) { console.log("The picture that was added hasn't been sized yet...") //The file needs to be resized... const workingDir = join(tmpdir(), 'thumbs'); const tmpFilePath = join(workingDir, fileName); // 1. Ensure thumbnail dir exists await fs.ensureDir(workingDir); // 2. Download Source File await bucket.file(filePath).download({ destination: tmpFilePath }); console.log("Downloaded the source file"); console.log(tmpFilePath); // 3. Resize the image ********THIS PART IS NOT HAPPENING CORRECTLY console.log("About to start resizing..."); const resizedfileName: string = fileName.split('@').pop(); const resizedFilePath = join(workingDir, resizedfileName); await sharp(tmpFilePath).resize(150, 150).toFile(resizedFilePath); console.log("The image resizing is complete: "+ resizedFilePath); // 4. Upload the resized image const resizedImageUploadSnapshot = await bucket.upload(resizedFilePath, {destination: join('profile-image', resizedfileName)}); console.log("Uploaded the resized image "); // 5. Cleanup remove the tmp/thumbs from the filesystem await fs.remove(workingDir); console.log("FUNCTION COMPLETED SUCCESSFULLY!") return true; } else { return false; } } else { console.log('exiting function'); return false; } } catch (error) { console.log(error); return error; }
Have the same problem. More or lesse the same code Did you manage to solve it?
Hi, yes I did solve it but I don't remember exactly how at the moment. I can pull it up sometime this weekend and I'll post the new code. It wasn't an issue with the sharp api. It may have been that I needed to specify a file extension in all the file names?? I'll confirm back once I can look at the code.
Thank you so much :)
@avilao Sorry I couldn't get to this over the weekend! I've made a few other changes since this post, but I believe the one that resolved this issue was changing the following lines:
const tmpFilePath = join(workingDir, fileName + '.jpeg');
const resizedFilePathTemp = join(workingDir, resizedfileName + '.jpeg');
Let me know if that doesn't work! Good luck!
Something like that solved the issue. But I actually had to stop using sharp because of another issue (image data was from the previous upload, in Firebase functions) and am now using ImageMagick.
Thanks for the help :)
@avilao Re: "image data was from the previous upload" - if you're recycling the same filename for different images then you'll need to disable libvips cache.
Most helpful comment
@avilao Re: "image data was from the previous upload" - if you're recycling the same filename for different images then you'll need to disable libvips cache.