Higher resolution for screen captures of 3D view?

Hi, just wondering if high-res screen capture ever proceeded beyond the discussion of the possibility in this thread. It’s something I’d want to make use of, if the capability is there. Thanks,

Yes, you can increase the output dimensions by specifying the scaling factor (e.g., if your screen is 1920x1080, scaling x2 would give you a 3840x2160 output). However, make sure you switch to 3D only layout first and use full layout option in screen capture.

image

1 Like

do you know some python code for this scale factor

Full layout is just digital zoom, so it just makes the image bigger but does not improve image quality.

Rendering of individual views actually increases the resolution but it is currently broken. Slicer’s VTK version will be upgraded in a couple of weeks, there is a chance that it will fix the high-resolution rendering.

its any python code for this rendering I’m using the 4.10.2 version because it supports FreeSurferLabel

also if theres any code for this scale factor (magnification factore) I would like to try it

Current Slicer release has this label, too, just install SlicerFreeSurfer extension.

You can use any of the capture code snippets in the script repository. Right now, there is no benefit in using the annotation screenshot tool and adjusting the scaling factor.

I have this code
#########

viewNodeID = ‘vtkMRMLSliceNodeRed’
import ScreenCapture
cap = ScreenCapture.ScreenCaptureLogic()
view = cap.viewFromNode(slicer.mrmlScene.GetNodeByID(viewNodeID))
cap.captureImageFromView(view,‘C:/Users/aldot/Desktop/python/Red.png’)

#########
but I also want to change the Scale factor lets say to 3 and that information is not in capture code snippets in the script repository

image

We will make sure the scale factor is exposed in Python when scaling gets fixed.

1 Like

thanks for your reply.

Hi there. I am interested to rehash this previous forum (RE. exporting high quality images from the 3D view). It is such valuable data to properly showcase.

In the end, does adjusting the “scale factor” remain the only current option? OR have there been any changes since the last post in 2021?

Thanks,
Dale

You made me curious, so I tried offscreen rendering and it basically works, although it sometimes leads to a crash when interacting with the view after rendering. But something like the code below could be added as a feature if someone wants to play with it. It could use more tweaks, but if it’s useful for people we could put it in the script repository for now.

Here’s the full res 5kx5x version:


vtk.vtkGraphicsFactory()
gf = vtk.vtkGraphicsFactory()
gf.SetOffScreenOnlyMode(1)
gf.SetUseMesaClasses(1)
rw = vtk.vtkRenderWindow()
rw.SetOffScreenRendering(1)
ren = vtk.vtkRenderer()
rw.SetSize(5000,5000)

lm = slicer.app.layoutManager()
ren3d = lm.threeDWidget(0).threeDView().renderWindow().GetRenderers().GetItemAsObject(0)
actors = ren3d.GetActors()
for index in range(actors.GetNumberOfItems()):
    ren.AddActor(actors.GetItemAsObject(index))
lights = ren3d.GetLights()
for index in range(lights.GetNumberOfItems()):
    ren.AddLight(lights.GetItemAsObject(index))
volumes = ren3d.GetVolumes()
for index in range(volumes.GetNumberOfItems()):
    ren.AddVolume(volumes.GetItemAsObject(index))
camera = ren3d.GetActiveCamera()
ren.SetActiveCamera(camera)


rw.AddRenderer(ren)
rw.Render()

wti = vtk.vtkWindowToImageFilter()
wti.SetInput(rw)
wti.Update()
writer = vtk.vtkPNGWriter()
writer.SetInputConnection(wti.GetOutputPort())
writer.SetFileName("/tmp/out.png")
writer.Update()
writer.Write()
i = wti.GetOutput()

Here’s an inset of what the full resolution looks like:

image

3 Likes

Here’s an example with volume rendering at 5k x 5k:

The crashes are because actors are not meant to be shared across render windows like this script does, but for doing one-off renders this works. If someone wants to give it a shot, integrating off-screen rendering properly with the application wouldn’t be too hard since we know it will work.

1 Like

I’d like to second this question 2.5 years later: is high-resolution screen capture possible? I tried last week and had the same issue described with the scaling factor (increases size, but not resolution). It’s one big thing keeping Slicer from being a complete solution for descriptive research.

Did you try the workaround posted above?

I did, twice. I tried before I posted and the program froze. I tried again line by line just now and it did write an image file this time, but the image was 72 kb and completely blank. Admittedly, I’m a novice to Slicer and python is very, very rusty.

It may just take time to render a big image. That code tries to make a 5k x 5k image and maybe that’s bigger than you need or maybe you can try on a different computer. I tested on a mac pro with lots of memory.

Okay, it’s working now to take the kind of images you included, but there’s one more hurdle I can’t figure out how to overcome:

For a lot of publication-quality imagery, I need a scale bar. I’ve tried modifying your example to change the view node by modifying line 10 into:

lm = slicer.app.layoutManager()
view = lm.threeDWidget(0).threeDView()
view.mrmlViewNode().SetRenderMode(1)
view.mrmlViewNode().SetRulerType(1)
view.mrmlViewNode().SetRulerColor(2)
ren3d = view.renderWindow().GetRenderers().GetItemAsObject(0)

And that might change the view I can see in Slicer, but it doesn’t change what gets written to the file. I’ve been trying to follow the code and it seems I’m not properly accessing what gets added to the vtkRenderer…where do rulers interact with the renderer?

Right, the example I pasted above only transfers some of the basic elements of the rendered scene over to the high res rendering. The Color Legend and rulers are rendered as overlays so they would need to be added to the script. I don’t recall, but they may be in dedicated renderers. It should be possible to add them if you study the vtk code and the slicer displayable managers, but I believe they are rendered in pixel space, meaning they could look very small in the resulting images (this would be a problem in the original scale factor approach too). If you just need the reference ruler, you might just add a markup line of the reference size and set the thickness so it looks nicer.

Thank you for the suggestions. I followed the latter and got it working well enough.

If anyone else is looking to something similar in the future, I modified the example code at the link here to create a horizontal markup line of desired size, then ran the rest of the scene rendering / writing code. The line was included in the image and functioned perfectly well as a scale bar.