# Creating a screenshot by script

**URL:** <https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328>\
**Category:** Support\
**Created:** [January 4, 2021, 11:25am UTC](https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328 "2021-01-04T11:25:36Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Justin](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Justin](https://discourse.slicer.org/u/Justin)\
**Post date:** [January 4, 2021, 11:25am UTC](https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328/1 "2021-01-04T11:25:36Z")

</div>

Dear all,

I have a question concerning creating a screenshot using ScreenCapture.  
I found the relevant script on the repository on the website

```
viewNodeID = 'vtkMRMLSliceNodeRed'
import ScreenCapture
cap = ScreenCapture.ScreenCaptureLogic()
view = cap.viewFromNode(slicer.mrmlScene.GetNodeByID(viewNodeID))
cap.captureImageFromView(view,sceneSaveDirectory + "/segmentation export.png")

```

(`sceneSaveDirectory` is defined previously to this section of the script)

When I paste this script in the interactor it works as expected  
However when I run this script as a part of a larger script (copy-pasted in the Python Interactor) it does not work.  
No error is shown, the screenshot is just not generated.

I tried running a `time.sleep(3)` before and after this section, but this does not fix the problem.  
If I paste each section of the script separately into the Python Interactor it _does_ work, just not when I paste it as a whole.

Do you have a suggestion how to fix this?

Thanks in advance,  
Justin

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [January 4, 2021, 1:58pm UTC](https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328/2 "2021-01-04T13:58:39Z")

</div>

You can try `slicer.app.processEvents()` instead.

---

<div class="post-metadata">

**Author:** ![cpinter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/cpinter/32/7995_2.png) [@cpinter](https://discourse.slicer.org/u/cpinter)\
**Post date:** [January 4, 2021, 2:06pm UTC](https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328/3 "2021-01-04T14:06:40Z")

</div>

I find this quite strange. The script works for me in 4.11.20200930 and a recent preview as well on Windows. What Slicer version and operating system do you use?

---

<div class="post-metadata">

**Author:** ![Justin](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Justin](https://discourse.slicer.org/u/Justin)\
**Post date:** [January 4, 2021, 2:51pm UTC](https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328/4 "2021-01-04T14:51:22Z")

</div>

Thanks for your reply!

@pieper: I tried switching the `time.sleep(3)` to `slicer.app.processEvents()` both before and after this script but that didn’t work. Was that a correct interpretation of your suggestion? (so that the script waits until it is finished processing, rather than just 3 seconds?)

@cpinter

I use Windows 10 and the Nightly slicer version of 2020-12-07  
As said above, this part of the script on its own works fine, but not as a part of a bigger script:

I load a CT-scan from the dicom library  
Then I use a script to rename the volume, create a segmentation. It then pauses so that I can manually segment everything and then the script continues to process the segmentations, save the scene and close. So basically I can process each scan by just pasting in the whole script.

I inserted the above script to be able to export a view of the segmentations, but it does not work as part of my bigger ‘workhorse’ script. (but does work when I just paste the lines above).

Hopefully that’s a better explanation of the situation.

---

<div class="post-metadata">

**Author:** ![cpinter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/cpinter/32/7995_2.png) [@cpinter](https://discourse.slicer.org/u/cpinter)\
**Post date:** [January 4, 2021, 2:54pm UTC](https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328/5 "2021-01-04T14:54:41Z")

</div>

> [@Justin](#):
>
> but not as a part of a bigger script

In this case a self-contained test case would help a lot.

---

<div class="post-metadata">

**Author:** ![Justin](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Justin](https://discourse.slicer.org/u/Justin)\
**Post date:** [January 4, 2021, 5:56pm UTC](https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328/6 "2021-01-04T17:56:08Z")

</div>

This is an example where it does not work

```
import time
import os

## Selecting and renaming the volume
masterVolumeNode=slicer.mrmlScene.GetFirstNodeByClass('vtkMRMLScalarVolumeNode')

# Get patient's Name and rename the volume
instUids=masterVolumeNode.GetAttribute('DICOM.instanceUIDs').split()
filename=slicer.dicomDatabase.fileForInstance(instUids[0])
patientName=slicer.dicomDatabase.fileValue(filename,'0010,0010')
masterVolumeNode.SetName(patientName + '_CWK') 

## part 1: creating segments
# Create segmentation
segmentationNode = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSegmentationNode")
segmentationNode.SetName('test segmentation')
segmentationNode.CreateDefaultDisplayNodes() # only needed for display
segmentationNode.SetReferenceImageGeometryParameterFromVolumeNode(masterVolumeNode)

# Create segments by thresholding
segmentsFromHounsfieldUnits = [
    ["A", -29, 150],
    ["B", -29, 150],
    ["C", -29, 150] ]
for segmentName, thresholdMin, thresholdMax in segmentsFromHounsfieldUnits:
    # Create segment
    addedSegmentID = segmentationNode.GetSegmentation().AddEmptySegment(segmentName)

# Delete temporary segment editor
segmentEditorWidget = None

# Select SegmentEditor
m = slicer.util.mainWindow()
m.moduleSelector().selectModule('SegmentEditor')
layoutManager = slicer.app.layoutManager()
layoutManager.setLayout(6)

# wait for segmentation
try:
    input("Now perform your segmentation and press ENTER. If you push ENTER the screen will look unresponsive for a few seconds.")
except EOFError: pass

slicer.app.processEvents()

# Create a new directory where the scene will be saved into
sceneSaveDirectory = "D:/Slicer/test/" + patientName
if not os.access(sceneSaveDirectory, os.F_OK):
  os.makedirs(sceneSaveDirectory)

slicer.app.processEvents()

viewNodeID = 'vtkMRMLSliceNodeRed'
import ScreenCapture
cap = ScreenCapture.ScreenCaptureLogic()
view = cap.viewFromNode(slicer.mrmlScene.GetNodeByID(viewNodeID))
cap.captureImageFromView(view,sceneSaveDirectory + "/segmentation export.png")

#time.sleep(3)
slicer.app.processEvents()

# Save the scene
if slicer.app.applicationLogic().SaveSceneToSlicerDataBundleDirectory(sceneSaveDirectory, None):
  logging.info("Scene saved to: {0}".format(sceneSaveDirectory))
else:
  logging.error("Scene saving failed")   

slicer.mrmlScene.Clear(0)
m.moduleSelector().selectModule('DICOM')

```

If I comment out (or remove) the last two lines and paste this after running the above script:

```
viewNodeID = 'vtkMRMLSliceNodeRed'
import ScreenCapture
cap = ScreenCapture.ScreenCaptureLogic()
view = cap.viewFromNode(slicer.mrmlScene.GetNodeByID(viewNodeID))
cap.captureImageFromView(view,sceneSaveDirectory + "/segmentation export.png")

```

then the exported screenshot does appear

---

<div class="post-metadata">

**Author:** ![cpinter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/cpinter/32/7995_2.png) [@cpinter](https://discourse.slicer.org/u/cpinter)\
**Post date:** [January 5, 2021, 8:59am UTC](https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328/7 "2021-01-05T08:59:03Z")

</div>

I was able to spend a little time on this. Indeed, using your script the screenshot is not saved for some reason. I noticed that if the scene is not saved after capturing the screenshot, then the screenshot is saved alright, which is strange.

If the order of the commands does not matter, then I suggest simply saving the screenshot after saving the scene. However, I don’t have an explanation about the screenshot not being saved with your snippet without some more serious debugging.

---

<div class="post-metadata">

**Author:** ![Justin](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Justin](https://discourse.slicer.org/u/Justin)\
**Post date:** [January 5, 2021, 10:50am UTC](https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328/8 "2021-01-05T10:50:14Z")

</div>

Thanks for taking the time looking into this, I agree that changing the order of the script is the easiest way to go. For now the order of the commands do not matter, so I can work with it!

I’ve just taken another look and added a pause after saving the screenshot.  
It appears that the screenshot is written, but it is then deleted by the ‘save scene’ part of the script.  
That is `SaveSceneToSlicerDataBundleDirectory()`

When I look it up in the APIdocs I do not see a means to prevent overwriting the entire folder.  
To me this is a problem, as I might want to add other segmentations to this folder later on.  
Do you know if it is possible to save the files without overwriting the entire folder contents?

---

<div class="post-metadata">

**Author:** ![cpinter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/cpinter/32/7995_2.png) [@cpinter](https://discourse.slicer.org/u/cpinter)\
**Post date:** [January 5, 2021, 12:50pm UTC](https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328/9 "2021-01-05T12:50:03Z")

</div>

OK makes sense, so the scene saving function clears the folder.

What is your goal with the screenshot in the same folder? I’m asking because usually people save scenes in an MRB file, which is self-contained, much easier to manage because it’s a single file, and can be loaded in Slicer the same way as a MRML file that has a Data folder.

---

<div class="post-metadata">

**Author:** ![Justin](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Justin](https://discourse.slicer.org/u/Justin)\
**Post date:** [January 6, 2021, 1:27pm UTC](https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328/10 "2021-01-06T13:27:02Z")

</div>

Thanks, my idea was that I want to create multiple 2D segmentations (so at different axial levels of the body)  
I wanted to create a snapshot, so that I can preview each segmentation while not having to open the entire scene.

so the folder structure would be

Patient A  
– segmentation 1 preview.png  
– segmentation 2 preview.png  
– scene.mrml  
– “Data” folder containing all the data

Patient B  
– segmentation 1 preview.png  
– segmentation 2 preview.png  
– scene.mrml  
– “Data” folder containing all the data

I think I’ll work around this issue by saving all the screenshots in a separate folder (so not in the patient folder)

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [January 6, 2021, 2:16pm UTC](https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328/11 "2021-01-06T14:16:44Z")

</div>

> [@Justin](#):
>
> It appears that the screenshot is written, but it is then deleted by the ‘save scene’ part of the script.  
> That is `SaveSceneToSlicerDataBundleDirectory()`

It is essential to clean the output folder before MRML scene bundle export because when MRB file is generated from the entire content of the folder. You do not want random files that pre-exist in that folder show up in your MRB file. Whatever you want to save into the MRB file, you can add it to the scene (for example, if you want to include an additional png file then you can load it into the scene as an image volume).

> [@Justin](#):
>
> I wanted to create a snapshot, so that I can preview each segmentation while not having to open the entire scene.

Yes, if you have a custom folder structure then you can rearrange Slicer’s default output any way you want.

> [@Justin](#):
>
> Thanks, my idea was that I want to create multiple 2D segmentations (so at different axial levels of the body)

I would strongly recommend to use a 3D viewer to review segmentations. Very often you don’t notice segmentation errors (or may think that a valid segmentation is incorrect), unless you review the segmentation along at least 3 orthogonal axes. Even if you export 3 image stacks, you will have trouble reviewing the data, because it is hard to find corresponding slice views for a specific 3D position.

Latest Slicer Preview Release is fully portable: you can just copy the application files to a USB stick along with the images extensions and provide a batch file that launches Slicer and iterates through all the images with a convenient user interface (for example, using [CaseIterator extension](https://github.com/JoostJM/SlicerCaseIterator) or the DICOM browser).

If you want to avoid your users to run a desktop application then you can export segmentation as DICOM segmentation object and review along with the images in a DICOMweb browser in your web browser using [Kheops](https://kheops.online/) or using your cloud services or your own server.

---

<div class="post-metadata">

**Author:** ![Justin](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Justin](https://discourse.slicer.org/u/Justin)\
**Post date:** [January 10, 2021, 10:59am UTC](https://discourse.slicer.org/t/creating-a-screenshot-by-script/15328/12 "2021-01-10T10:59:48Z")

</div>

Thanks Andras for your explanation. If you explain it, it makes sense to keep the folder empty.  
And it is a useful suggestion to add the export to the scene!

I only have one more question: For the scans I use `controller.rotateSliceToBackground()` and when I add a .png to the scene, the image is not shown in one view, but is also rotated, so I have to scroll to see the entire image.  
And If I rotate the .png to be shown in one view, the scan is also rotated.

Is it possible that the .png is not rotated when I import it to the scene?

Thanks for your help so far! Justin
