Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Proof-of-concept script showing one whole slide image as an overlay on top
- * of another within QuPath.
- *
- * Note that this script simply overlays the *same* image that is currently open;
- * therefore it may not be immediately obvious that anything has happened.
- *
- * Uncomment the line
- * g2d.translate(1000, 1000)
- * if you want to convince yourself that something *has* actually happened,
- * and adjust the opacity slider as required.
- *
- * In practice, it will be more useful to overlay a *different* image...
- *
- * Note that you can also optionally bind the overlay display to the show/hide detections option.
- *
- * WARNING! This should work in QuPath v0.1.2, and possibly v0.1.3.
- * However, the API will definitely change in the future as overlays become
- * a more important part of the software... therefore be prepared to update any
- * code based on this.
- *
- * @author Pete Bankhead
- */
- import javafx.application.Platform
- import qupath.lib.awt.common.AwtTools
- import qupath.lib.gui.viewer.QuPathViewer
- import qupath.lib.gui.viewer.overlays.AbstractImageDataOverlay
- import qupath.lib.images.ImageData
- import qupath.lib.images.servers.ImageServer
- import qupath.lib.images.servers.ImageServerProvider
- import qupath.lib.regions.ImageRegion
- import qupath.lib.scripting.QPEx
- import java.awt.Graphics2D
- import java.awt.Shape
- import java.awt.geom.AffineTransform
- import java.awt.image.BufferedImage
- import java.awt.image.ImageObserver
- // Replace overlay in the Application thread
- Platform.runLater {
- def viewer = QPEx.getCurrentViewer()
- def path = viewer.getServerPath()
- def overlay = new WholeSlideImageOverlay(viewer, path, false)
- // Remove any existing overlays of this kind (helpful during debugging...)
- viewer.getOverlayLayers().findAll({it.getClass().getName().contains('WholeSlideImageOverlay')}).each {
- viewer.removeOverlay(it)
- }
- // Add the new overlay
- viewer.addOverlay(overlay)
- print 'Done!'
- }
- /**
- * Create an overlay to display one whole slide image on top of another.
- */
- class WholeSlideImageOverlay extends AbstractImageDataOverlay {
- private boolean initialized = false
- private QuPathViewer viewer
- private ImageServer<BufferedImage> server
- private AffineTransform transform
- private boolean bindToObjectDisplay
- public WholeSlideImageOverlay(final QuPathViewer viewer, final String path, boolean bindToObjectDisplay) {
- super(viewer.getOverlayOptions(), viewer.getImageData())
- this.viewer = viewer
- this.server = ImageServerProvider.buildServer(path, BufferedImage.class)
- this.initialized = true
- this.bindToObjectDisplay = bindToObjectDisplay
- }
- @Override
- boolean supportsImageDataChange() {
- return true
- }
- /**
- * If the ImageData for the viewer is changed, remove the overlay.
- *
- * @param imageData
- */
- @Override
- public void setImageData(final ImageData<BufferedImage> imageData) {
- if (this.imageData == imageData || !initialized)
- return
- viewer.removeOverlay(this)
- this.server.close()
- }
- @Override
- void paintOverlay(Graphics2D g2d, ImageRegion imageRegion, double downsampleFactor, ImageObserver observer, boolean paintCompletely) {
- // Don't do anything if opacity is zero
- if (getOpacity() == 0)
- return
- // If we're binding this to the display of objects, don't paint if detections aren't visible
- // (this lets us toggle the overlay on & off with the 'h' shortcut)
- if (bindToObjectDisplay && !viewer.getOverlayOptions().showObjects)
- return
- // Create a rectangle for the region
- Shape shape = AwtTools.getBounds(imageRegion)
- // Apply transform... handy if using the same image, just to check *something* happens
- // g2d.translate(1000, 1000)
- // Paint region with the help of the image region store (used for caching & painting)
- int z = viewer.getZPosition()
- int t = viewer.getTPosition()
- viewer.getImageRegionStore().paintRegion(
- server, g2d, g2d.getClip(), z, t, downsampleFactor,
- viewer.getImageRegionStore().getThumbnail(server, z, t, true),
- null, null)
- }
- }
Add Comment
Please, Sign In to add comment