A way to screencapture and send to print with one button?

Hi guys,

I am wondering how one would go about having a physical button, from Arduino for example, which when pressed, makes a screencapturetofile (with transparent background), saves the file and sends it to a printer.

I have no experience scripting. Would it be too complicated?

Any ideas on how to achieve is?

On the Rhino side have a plug-in that listens for events from your device. When one you are interested in run the view capture and print commands, maybe just the print is enough (haven’t used it before).

You’ll probably have a client software, or driver of sorts, running on your computer to which the device is attached.

I wouldn’t be surprised if there are already solutions for arduino that makes hardware look like a joystick for instance, so you could handle events for that family of devices

Thank you for the reply.

Still, I was hoping if someone could point me in the right direction regarding Rhino’s shennenigans. I imagine a scrip is needed.

It would screenshot, save file, and send to peinter with presetted settings. I have no idea where to start with that.

Like how could this be done thorough the python language for instance?

Here’s the component I usually use to document Rhino/Grasshopper modelling stuff:


"""
Captures the Rhino viewport to an image file. Places the image in a folder called
Captures in the same directory as the GH definition. Names the image the same as 
the GH defintion followed by _hourMinuteSecond. Edit the script directly to set more options.
Note: Do not use this script with the GH button, freezes up the canvas for some reason.

    Inputs:
        Toggle: Activate the component using a boolean toggle. Do NOT use a Button {item,bool}
        BackgroundColor: Set the color of the Rhino viewport background {item,color,optional}
        Grid: Turn on the grid {item,bool,optional}
        WorldAxes:Turn on the world axes {item,bool,optional}
        CPlaneAxes: Turn on the cplane axes {item,bool,optional}
        OpenFile: If true the image will open in the default application {item,bool,optional}
    Outputs:
        Path: The path of the captured image {item,str}
    Remarks:
        Author: Anders Holden Deleuran
        License: Apache License 2.0
        Version: 160805
"""
ghenv.Component.Name = "ViewportCaptureToFile"
ghenv.Component.NickName ="VCF"

import os
import datetime
import System
import scriptcontext as sc
import Rhino as rc

def checkOrMakeFolder():
    
    """ Check/makes a "Captures" folder in the GH def folder """
    
    if ghdoc.Path:
        folder = os.path.dirname(ghdoc.Path)
        captureFolder = folder + "\\Captures"
        if not os.path.isdir(captureFolder):
            os.makedirs(captureFolder)
        return captureFolder

def makeFileName():
    
    """ Make a string with the gh def name + current hourMinuteSecond """
    
    # Make hour minute seconds string
    n = datetime.datetime.now()
    ho,mt,sc = str(n.hour),str(n.minute),str(n.second)
    if len(ho) == 1:
        ho = "0"+ ho
    if len(mt) == 1:
        mt = "0"+mt
    if len(sc) == 1:
        sc = "0"+ sc
    hms = ho+mt+sc
    
    # Get name of GH def
    ghDef = ghenv.LocalScope.ghdoc.Name.strip("*")
    
    # Concatenate and return
    fileName = ghDef + "_" + hms
    
    return fileName

def captureActiveViewToFile(width,height,path,grid,worldAxes,cplaneAxes):
    
    """
    Captures the active view to an image file at the path. Path looks like this:
    "C:\\Users\\adel\\Desktop\\Captures\\foooo_112747.png"
    """
    
    # Set the script context to the current Rhino doc
    sc.doc = rc.RhinoDoc.ActiveDoc
    
    # Get the active view and set image dimensions
    activeView = sc.doc.Views.ActiveView
    imageDim = System.Drawing.Size(width,height)
    
    # Perform the capture
    try:
        imageCap = rc.Display.RhinoView.CaptureToBitmap(activeView,imageDim,grid,worldAxes,cplaneAxes)
        System.Drawing.Bitmap.Save(imageCap,path)
        rc.RhinoApp.WriteLine(path)
        return path
    except:
        raise Exception(" Capture failed, check the path")

# Set background color
if BackgroundColor:
    rc.ApplicationSettings.AppearanceSettings.ViewportBackgroundColor = BackgroundColor

# Capture
if Toggle:
    
    if not Width:
        Width = 1920
    if not Height:
        Height = 1080
        
    capFolder = checkOrMakeFolder()
    fileName = makeFileName()
    try:
        path = os.path.join(capFolder,fileName + ".png")
        Path = captureActiveViewToFile(Width,Height,path,Grid,WorldAxes,CPlaneAxes)
        if OpenFile:
            os.startfile(path)
    except:
        raise Exception(" Capture failed, save the GH definition")

181217_ViewportCaptureToFile_GHPython.gh (6.7 KB)

Should get you going with capture bits at least. I’d imagine you can use the os module to send the file to a printer as well (using os.startfile(filename, "print").

Thank you Anders, this is great, as a tool and as an example code to learn!

I was able to concatenate the code you so kindly provided with the printing function, but I am missing the confirmation on the printing window… I need this to be fully automatic, meaning I can touch the keyboard to press enter.

I have been reading about this and it seems I need to install Pynput, but I am not sure the GH Python component has access to external libraries, isn’t there a simple way to make Python “press” enter?

Based on the AndersDeleuran code, I made a scraper capturing important slides images and model data. It was a personal demand when working with galapagos. Now I can gather the important information in a CSV spreadsheet and the images generated during the Galapagos process for a much greater work of optimization. Code and example available at link:

github

Uploading: 07.gif…

1 Like

Forgot to update this code to work with rendered viewport modes (i.e. by setting the transparent background flag to false to ensure no weird alpha shadow issues):

"""
Capture the Rhino viewport to a PNG file. Places the image in a folder called
Captures in the same directory as the GH definition. Names the image the same as 
the GH defintion followed by _hourMinuteSecond. Note: Do not use this script with
the GH button as this can freeze up the canvas.
    Inputs:
        Width: Width of PNG in pixels {item,int,optional}
        Height: Height of PNG in pixels {item,int,optional}
        Grid: Capture Rhino grid {item,bool,optional}
        Axes: Capture Rhino world axes {item,bool,optional}
        Open: Opens PNG in default application {item,bool,optional}
        Write: Write the captured bitmap to PNG file {item,bool}
    Outputs:
        Path: Path of captured PNG {item,str}
    Remarks:
        Author: Anders Holden Deleuran
        Version: 230830
"""

ghenv.Component.Name = "ViewportCapturePNG"
ghenv.Component.NickName ="VCPNG"

import os
import datetime
import System
import scriptcontext as sc
import Rhino as rc

def checkOrMakeFolder():
    
    """ Check/makes a "Captures" folder in the GH def folder """
    
    if ghdoc.Path:
        folder = os.path.dirname(ghdoc.Path)
        captureFolder = folder + "\\Captures"
        if not os.path.isdir(captureFolder):
            os.makedirs(captureFolder)
        return captureFolder

def makeFileName():
    
    """ Make a string with the gh def name + current hourMinuteSecond """
    
    # Make hour minute seconds string
    n = datetime.datetime.now()
    ho,mt,sc = str(n.hour),str(n.minute),str(n.second)
    if len(ho) == 1:
        ho = "0"+ ho
    if len(mt) == 1:
        mt = "0"+mt
    if len(sc) == 1:
        sc = "0"+ sc
    hms = ho+mt+sc
    
    # Get name of GH def
    ghDef = ghenv.LocalScope.ghdoc.Name.strip("*")
    
    # Concatenate and return
    fileName = ghDef + "_" + hms
    
    return fileName

def captureActiveViewToFile(width,height,path,grid,worldAxes,cplaneAxes):
    
    """ Capture active view to .PNG file at path """
    
    # Define view capture settings (you might want to edit these)
    vc = rc.Display.ViewCapture()
    vc.Width = width
    vc.Height = height
    vc.DrawGrid = grid
    vc.DrawGridAxes = grid
    vc.DrawAxes = worldAxes
    vc.TransparentBackground = False
    vc.ScaleScreenItems = False
    
    # Perform the capture
    try:
        bitmap = vc.CaptureToBitmap(rc.RhinoDoc.ActiveDoc.Views.ActiveView)
        System.Drawing.Bitmap.Save(bitmap,path)
        rc.RhinoApp.WriteLine(path)
        return path
    except:
        raise Exception("Capture failed, check path")

# Capture
if Write:
    if not Width:
        Width = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width  
    if not Height:
        Height = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height
    folder = checkOrMakeFolder()
    fileName = makeFileName()
    try:
        path = os.path.join(folder,fileName + ".png")
        Path = captureActiveViewToFile(Width,Height,path,Grid,Axes,Grid)
        if Open:
            os.startfile(path)
    except:
        raise Exception(" Capture failed, save the GH definition")
else:
    Path = []

230830_ViewportCapturePNG_00.gh (4.7 KB)