Reputation: 281
Following this advice I am trying to replace our usage of viewer::getScreenshot
with Autodesk.Viewing.ScreenShot.getScreenShotWithBounds
which calls Autodesk.Viewing.ScreenShot.getScreenShot
to support larger screenshots. However, the bounds are ignored. The behaviour seems to be that it makes a screenshot of the viewer's default camera or corresponding to its dimensions. Then it stretches the image to fit the given width and height. I expected the function to return a screenshot of the elements inside the given bounding box.
Is the function getScreenShotWithBounds
supposed to do something different from what I am assuming?
Example code (LMV 7.40.0):
const bbounds: THREE.Bbox3; // calculated for some elements I want to screenshot
Autodesk.Viewing.ScreenShot.getScreenShotWithBounds(NOP_VIEWER, Math.ceil(bbounds.size().x * 4), Math.ceil(bbounds.size().y* 4), (blob) => window.open(blob), {bounds: bbounds, margin: 0});
I misunderstood the function. Autodesk.Viewing.ScreenShot.getScreenShotWithBounds
just fits the bounds into the camera view. The bounds are not used for any cropping. See my more detailed answer.
Upvotes: 1
Views: 250
Reputation: 281
The given width and height of Autodesk.Viewing.ScreenShot.getScreenShotWithBounds
must be of the same aspect ratio as the viewer (see Adam Nagy's answer), i.e.:
getScreenShotWithBounds(NOP_VIEWER, NOP_VIEWER.getDimensions().width * 4, NOP_VIEWER.getDimensions().height * 4, options);
getScreenShotWithBounds
just fits the bounds into the camera view (internally it calls viewer.navigation.fitBounds(true, bounds, false);
). The bounds are not used for any kind of cropping / pixel calculation or otherwise.
To get a specific aspect ratio by cropping, you have to provide getCropBounds
in the options
parameter.
For example to force a aspect ratio by cropping:
getCropBounds: function(viewer: Autodesk.Viewing.Viewer3D, camera: Autodesk.Viewing.UnifiedCamera, bounds: THREE.Box3): THREE.Box2 {
// calculate the crop bounds in pixels
// if the crop bounds are larger the screenshot's width / height is taken
const aspectRatio = new THREE.Vector2(4, 3);
const viewerBoundsWidthRatio = width / aspectRatio.x;
const viewerBoundsHeightRatio = height / aspectRatio.y;
const cropToHeight = viewerBoundsWidthRatio > viewerBoundsHeightRatio;
const smallerScaleRatio = cropToHeight ? viewerBoundsHeightRatio : viewerBoundsWidthRatio;
const cropBoundsSize = aspectRatio.clone().multiplyScalar(smallerScaleRatio);
const cropBounds = new THREE.Box2(new THREE.Vector2(0, 0), new THREE.Vector2(cropBoundsSize.x, cropBoundsSize.y));
const offset = cropToHeight ? new THREE.Vector2((width - cropBoundsSize.x) / 2, 0) : new THREE.Vector2(0, (height - cropBoundsSize.y) / 2);
cropBounds.min.add(offset);
cropBounds.max.add(offset);
return cropBounds;
}
Upvotes: 2
Reputation: 2125
The squashed image you are getting is suggesting it, but it's not clear from the comments in the source code, that you should keep the ratio of the Viewer for the width
and height
input parameters. So you should only scale them depending on your needs: getScreenShotWithBounds(NOP_VIEWER, viewer_width * x, viewer_height * x, etc
Then the bounds
in the options
should take care of the cropping.
Upvotes: 1