Screenshot with all the layer and screenshot only one layer

Hi,
I'm trying to do a screenshot of all the layers of a gds file.
Right now I've managed to take a screenshot but it doesn't contain all the layers. (see code below)

include RBA

tailleX=500
tailleY=500
imgsave=ENV['HOME']+"/imagesGDS/"+File.basename($gdsfile, ".gds")+".png"

if (File.exist?(imgsave))
     exit
end

mw = RBA::Application::instance.main_window
mw.load_layout($gdsfile,1)
mw.current_view.save_image(imgsave,tailleX,tailleY)

I would like to be able to select a specific layer as well as select all the layers if possible.
Thank you.

Comments

  • Not sure this is helpful, but seems a lot simpler to
    just "Show All" or "Show Only Selected" in the layer
    window, and Alt-Pr-Scrn? I mean, even invoking the
    script takes more keyboard / mouse activity than
    that.

    But I'd expect that those menu-clicks have a hook
    somewhere in the pile-o'-functions.

  • Hi, Florent!

    You could access layer properties using LayoutView.begin_layers() that returns iterator. Then <iterator>.current().visible (of LayerProperties type) allows to control visibility.

    For example (sorry for Python-centrism):

    it = current_view.begin_layers()
    while not it.at_end():
           it.current().visible = use criteria for visibility there, for example, based on it.current().source_layer and source_datatype
           it.next()
    
  • edited January 2021

    Okay finally worked my way around this.
    I searched deeper in the forum and found something that works :)
    I'll leave the code here if someone want to use it. (not the cleanest thing I've done)

    include RBA
    
    tailleX=500
    tailleY=500
    imgsave=ENV['HOME']+"/imagesGDS/"+File.basename($gdsfile, ".gds")+".png"
    imgpics=ENV['HOME']+"/imagesGDS/"+File.basename($gdsfile, ".gds")+"_pics.png"
    
    if (File.exist?(imgpics))
        if (File.exist?(imgsave))
            exit
        end
    end
    
    mw = RBA::Application::instance.main_window
    mw.load_layout($gdsfile,0)   # $gdsfile is used in another script
    layer_view = mw.current_view
    layer_view.max_hier
    
    #export an image of all the layers
    mw.current_view.save_image(imgsave,tailleX,tailleY)
    
    view = RBA::LayoutView::current
    
    li = view.begin_layers
    while !li.at_end?
      lp = li.current
      if lp.source_layer == 1 && lp.source_datatype == 0
        new_lp = lp.dup
        new_lp.visible = true
        view.set_layer_properties(li, new_lp)
      else
        new_lp.visible = false
        view.set_layer_properties(li, new_lp)
      end
      li.next
    end
    #export an image of only one layer
    mw.current_view.save_image(imgpics,tailleX,tailleY)
    

    Topic that helped me: changing-the-layer-visibility-by-using-ruby

  • Yes, very good! Thanks for sharing the code! :)

    The trick is "layer_view.max_hier". Without that you just get cell frames.

    Kind regards,

    Matthias

  • Hi Matthias-

    Is it possible to use the save_image or save_screenshot and have the layer panel included in the output image?

    Thanks,

  • HI mikamar

    by using this you can get the layer color, texture and border style image,

    view = pya.Application.instance().main_window().current_view()
    layer_iter = view.begin_layers()
    while not(layer_iter.at_end()):
        #get layer icons in image form
        pixels = view.icon_for_layer(layer_iter, 25, 10, 1).to_png_data())
        layer_iter.next()
    

    by combining the image and layer info into a widget, and using Qt Render to save user interface into a png
    we can have layer panel screen shot.

    import pya
    import os
    
    def view():
        return pya.Application.instance().main_window().current_view()
    
    class ScreenShotWidget(pya.QWidget):
        def __init__(self, parent = None):
            super(ScreenShotWidget, self).__init__()  
            self.l = pya.QLabel()
            self.layout = pya.QVBoxLayout()
            self.layout.addWidget(self.l)
            self.layout.addStretch()
            self.setLayout(self.layout)
    
        def getScreen(self):
            if view():
                self.l.setPixmap(pya.QPixmap().fromImage(view().get_image(400, 400)))
            else:
                self.l.setText("No layout opened to take screenshot from")                
    
    
    class LayerIconWidget(pya.QWidget):
        def __init__(self, parent = None):
            super(LayerIconWidget, self).__init__()  
            self.layout = pya.QVBoxLayout()
            self.setLayout(self.layout)
            self.setFixedWidth(100)
    
        def getLayerIcon(self):
            if view():
                while self.layout.count() > 0:
                    self.layout.removeItem(self.layout.itemAt (0))
                self.layout = pya.QVBoxLayout()
                self.setLayout(self.layout)                
                bgc  = view().get_config("background-color")
                txtc = "#FFFFFF" if (int(bgc[1:3], 16) + int(bgc[3:5], 16) + int(bgc[5:7], 16)) <= (255) else "#000000"
                layer_iter = view().begin_layers()
                self.setStyleSheet("background-color:%s;" % bgc)
    
                while not(layer_iter.at_end()):
                    layerPixmap = pya.QPixmap()
                    layerImage  = pya.QLabel(self)
                    layerLabel  = pya.QLabel(self)
                    layerLayout = pya.QHBoxLayout(self)
                    layerProp   = layer_iter.current()
                    layerLabel.setText(f"{layerProp.source_layer}/{layerProp.source_datatype}")
                    layerLabel.setStyleSheet("color:%s;" % txtc)
                    layerPixmap.loadFromData(view().icon_for_layer(layer_iter, 25, 10, 1).to_png_data())
                    layerImage.setPixmap(layerPixmap)
                    layerLayout.addWidget(layerImage)
                    layerLayout.addWidget(layerLabel)
                    layerLayout.addStretch()
    
                    self.layout.addLayout(layerLayout)
                    layer_iter.next()
                self.layout.addStretch()
                self.update()
    
    
    class LayerScreenShotWidget(pya.QWidget):
        def __init__(self, parent = None):
            super(LayerScreenShotWidget, self).__init__()  
            self.layerIconWidget  = LayerIconWidget()
            self.screenShotWidget = ScreenShotWidget()
            self.layout           = pya.QHBoxLayout()
            self.setStyleSheet("background-color:black;")
            self.layout.addWidget(self.layerIconWidget)
            self.layout.addWidget(self.screenShotWidget)
            self.setLayout(self.layout)
    
        def getScreen(self):
            self.setStyleSheet("background-color:%s;" % view().get_config("background-color"))
            self.screenShotWidget.getScreen()
            self.layerIconWidget.getLayerIcon()
            self.update()
    
    
        def saveScreen(self, path):
            basedir = os.path.dirname(path)
            if os.path.exists(basedir):
                widgetImage = pya.QPixmap(self.size)
                self.render(widgetImage)
                widgetImage.save(path)
                pya.QMessageBox.information(None, 'Status', 'file saved')
            else:
                 pya.QMessageBox.information(None, 'Status', 'Error: invalid path')
    
    
    class ScreenShotControlWidget(pya.QWidget):
        def __init__(self, parent = None):
            super(ScreenShotControlWidget, self).__init__()     
            self.layerScreenShotWidget = LayerScreenShotWidget()
            self.pathLabel             = pya.QLabel("Path:")
            self.pathEdit              = pya.QLineEdit()
            self.getScreenPB           = pya.QPushButton("Get image")
            self.saveScreenPB          = pya.QPushButton("Save Image")
            self.cancelPB              = pya.QPushButton("Cancel")
            self.ctrlLayout            = pya.QHBoxLayout()
            self.filePathLayout        = pya.QHBoxLayout()
            self.layout                = pya.QVBoxLayout()
    
    
    
            self.filePathLayout.addWidget(self.pathLabel)
            self.filePathLayout.addWidget(self.pathEdit)
            self.ctrlLayout.addWidget(self.getScreenPB)
            self.ctrlLayout.addWidget(self.saveScreenPB)
            self.ctrlLayout.addWidget(self.cancelPB)        
            self.layout.addWidget(self.layerScreenShotWidget)
            self.layout.addLayout(self.filePathLayout)
            self.layout.addLayout(self.ctrlLayout)
    
            self.setLayout(self.layout)
            self.getScreenPB.clicked(lambda : self.getScreen())
            self.saveScreenPB.clicked(lambda : self.layerScreenShotWidget.saveScreen(self.pathEdit.text))
    
            self.cancelPB.clicked(lambda : self.close())
            self.resize(500, 500)
            self.getScreen()
    
    
        def getScreen(self):
            filepath =  "\\".join(pya.CellView().active().filename().split("\\")[0:-1])
            filepath = (filepath if filepath else pya.Application.instance().klayout_path()[-2]) + "\\out.png"
            self.pathEdit.setText(filepath)
            self.layerScreenShotWidget.getScreen()
            self.update()
    
    
    screenShotControlWidget = ScreenShotControlWidget()
    screenShotControlWidget.show()
    
    
  • @RawrRanger Wow ... best screen shot feature I've seen so far. And nice documentation too!

Sign In or Register to comment.