Snapshot on annotation
basicsnapshotannotationsslide loader
Console
PMA.UI version: 2.43.3
Select an annotation and click the camera icon to snapshot its bounding region
Snapshot example using an annotation as bounding box.
snapshot_feature.html
1<!doctype >
2<html lang="en">
3
4<head>
5 <meta charset="utf-8">
6 <meta http-equiv="X-UA-Compatible" content="IE=10">
7 <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
8
9 <!-- Include PMA.UI required libraries downloaded or from CDN -->
10 <script src="./pma.ui/jquery-3.1.0.js"></script>
11 <link href="./pma.ui/font-awesome.min.css" type="text/css" rel="stylesheet">
12
13 <!-- Include optional libraries downloaded or from CDN -->
14 <link rel="stylesheet" href="./pma.ui/bootstrap.min.css">
15 <script src="./pma.ui/bootstrap.bundle.min.js"></script>
16
17 <!-- Include PMA.UI script & css -->
18 <script src="./pma.ui/pma.ui.js"></script>
19 <link href="./pma.ui/pma.ui.css" type="text/css" rel="stylesheet">
20
21 <!-- Include custom script & css -->
22 <script src="./js/snapshot_feature.js"></script>
23 <link href="./css/snapshot_feature.css" type="text/css" rel="stylesheet">
24
25 <title>Snapshot on annotations</title>
26</head>
27
28<body>
29 <div class="container-fluid">
30 <div class="row">
31 <div class="col-4 py-1 border-right">
32 <legend class="text-center">Snapshot options
33 <button type="button" class="btn btn-outline-secondary btn-sm" id="snapshot-btn"
34 title="Click to take snapshot" disabled>
35 <i class="fas fa-camera"></i>
36 </button>
37 </legend>
38 <form>
39 <div class="form-group row">
40 <label for="inputFormat" class="col-6 col-form-label col-form-label-sm">Format</label>
41 <div class="col-6">
42 <select class="form-control form-control-sm" id="inputFormat">
43 <option value="png">png</option>
44 <option value="jpg" selected>jpg</option>
45 </select>
46 </div>
47 </div>
48
49 <div class="form-group row">
50 <label for="inputScalebar" class="col-6 col-form-label col-form-label-sm">Scalebar</label>
51 <div class="col-6">
52 <select class="form-control form-control-sm" id="inputScalebar">
53 <option value="true">True</option>
54 <option value="false" selected>False</option>
55 </select>
56 </div>
57 </div>
58 <div class="form-group row">
59 <label for="inputFilename" class="col-6 col-form-label col-form-label-sm">Filename</label>
60 <div class="col-6">
61 <input type="text" class="form-control form-control-sm" id="inputFilename"
62 placeholder="snapshot">
63 </div>
64 </div>
65 </form>
66 </div>
67 <div class="col-8">
68 <div id="viewer"></div>
69 </div>
70 </div>
71 </div>
72</body>
73
74</html>
snapshot_feature.css
1html,
2body
3{
4 height: 100%;
5 padding: 0px;
6 margin: 0px;
7}
8
9#viewer
10{
11 height: 100vh;
12}
snapshot_feature.js
1// Initial declarations
2var serverUrl = "https://host.pathomation.com/pma.core.2/";
3var serverUsername = "PMA_UI_demo";
4var serverPassword = "PMA_UI_demo";
5var caller = "DemoPortal";
6var slideLoaderElementSelector = "#viewer";
7var imagePath = "wsiformats/annotations/CMU-1.svs";
8var slideLoader = null;
9
10jQuery(function () {
11 console.log(`PMA.UI version: ${PMA.UI.getVersion()}`);
12 console.log("Select an annotation and click the camera icon to snapshot its bounding region");
13 // Create a context
14 var context = new PMA.UI.Components.Context({ caller: caller });
15
16 // Add an autologin authentication provider
17 new PMA.UI.Authentication.AutoLogin(context, [{ serverUrl: serverUrl, username: serverUsername, password: serverPassword }]);
18
19 // Create an image loader that will allow us to load images easily
20 slideLoader = new PMA.UI.Components.SlideLoader(context, {
21 element: slideLoaderElementSelector,
22 annotations: {},
23 barcode: false,
24 });
25
26 // Listen for the slide loaded event by the slide loader
27 slideLoader.listen(PMA.UI.Components.Events.SlideLoaded, function (args) {
28 console.log("Slide loaded");
29 console.log(args);
30 $("#snapshot-btn").attr("disabled", false);
31 annotationManager = new PMA.UI.Components.Annotations({
32 context: context,
33 element: null,
34 viewport: slideLoader.mainViewport,
35 serverUrl: args.serverUrl,
36 path: args.path,
37 enabled: true
38 });
39
40 let f = slideLoader.mainViewport.annotationsLayer.getSource().getFeatures()[0];
41 annotationManager.selectInteraction.getFeatures().push(f);
42 });
43
44 // Listen for the slide info error event by slide loader
45 slideLoader.listen(PMA.UI.Components.Events.SlideInfoError, function (args) {
46 console.log("Slide info error");
47 console.log(args);
48 });
49
50 // Load the image with the context
51 slideLoader.load(serverUrl, imagePath);
52
53 $("#snapshot-btn").on("click", function () {
54 var format = $("#inputFormat").val();
55 var showScalebar = $("#inputScalebar").val() === "true";
56 var filename = $("#inputFilename").val();
57
58 console.log("Snapshot requested as " + format);
59 let feature = annotationManager.getSelection()[0];
60
61 let snapShotResult = slideLoader.mainViewport.getSnapshotUrl(false, null, format, showScalebar, null, filename, feature, null);
62 console.log(snapShotResult);
63 console.image(snapShotResult.url);
64 });
65});
66
67function getBox(width, height) {
68 return {
69 string: "+",
70 style: "font-size: 1px; padding: " + Math.floor(height / 2) + "px " + Math.floor(width / 2) + "px; line-height: " + height + "px;"
71 }
72}
73
74console.image = function (url) {
75 var img = new Image();
76
77 img.onload = function () {
78 let scale = Math.min(1, 450 / Math.max(this.width, this.height));
79 var dim = getBox(this.width * scale, this.height * scale);
80 console.log("%c" + dim.string, dim.style + "background: url(" + url + "); background-size: " + (this.width * scale) + "px " + (this.height * scale) + "px; color: transparent;");
81 };
82
83 img.src = url;
84};