If I have a file of dimensions 1999x1124, exif orientation=8, and I run it through sharp:
sharp(file).rotate().metadata().then(metadata => console.log(metadata))
I get the original metadata. I would have expected to see the new dimensions: (1124x1999) I tried inserting sharp.cache(false) after rotating, but that had no effect.
I suspect this is because the metadata function works "without decoding any compressed image data," and it would need to read the buffer in order to redetermine it? This seems broken to me. Shouldn't the rotate() function update whatever source it's pulling this metadata from?
Perhaps one non-breaking solution to this could be accepting a second options argument to the rotate method with a "resolveWithObject" flag that would work just like toBuffer, resolving an additional data object containing the new size after rotation. I don't particularly like this idea design-wise, just brainstorming.
My use-case is, I need to resize an overlay image down to match the rotated image, prior to applying it. I've had to resort to calling toBuffer twice: once to just fetch the dimensions, and then again after applying the overlay. It's just really ugly and inefficient. Here's the simplified version:
function applyOverlay(file, overlayFile) {
return sharp(file)
.rotate()
.toBuffer({resolveWithObject: true})
.then(async ({data, info}) => {
const newWidth = info.width;
const newHeight = info.height;
const overlay = await sharp(overlayFile)
.resize(newWidth, newHeight)
.max()
.toBuffer();
return sharp(data)
.overlayWith(overlay)
.toBuffer();
});
}
If there's some easier way to do this that I'm missing, by all means let me know where I've gone wrong. Thanks!
Hello, to perform a calculation based on EXIF Orientation without decoding pixel data, try something like the following (untested):
sharp(file)
.metadata()
.then(({ width, height, orientation }) => {
const [newWidth, newHeight] = orientation < 5
? [width, height]
: [height, width];
...
});
Ha, well that is ridiculously simple, thanks. I still think there's a case to be made for retrieving current metadata (or at least dimensions) at an arbitrary point in the pipeline, but this will work for my case.