KLayout / klayout

KLayout Main Sources
http://www.klayout.org
GNU General Public License v3.0
803 stars 205 forks source link

pya.LayoutView.save_image() without pya.Application #1914

Open lukasc-ubc opened 2 weeks ago

lukasc-ubc commented 2 weeks ago

Hi Matthias,

I would like to create an image of a layout, without relying on pya.Application.

Presently it requires the application (which can be headless) and LayoutView: https://www.klayout.de/doc-qt5/code/class_LayoutView.html#method208

My use case is generating an image in a Python script, automated in GitHub actions. Potentially I could download and install KLayout each time, but that would not be very efficient.

Thank you Lukas

srooks10 commented 2 weeks ago

Hi Lukas, It has been possible to generate an image of a layout using only the python module since release 0.28.0 (according to the release notes). Here is an example script from Mathias: https://www.klayout.de/forum/discussion/comment/9518/#Comment_9518 I've just checked it's running fine with klayout v0.29.6 from pypi.

As for downloading and installing KLayout each time, I do that too, to run DRC & LVS Ruby scripts. It takes 20 seconds on GitHub runners, most of that time being downloading the KLayout deb. If someone could suggest a better approach for the environment and to reduce KLayout hosting costs, I'm all ears. HTH, S.

sebastian-goeldi commented 2 weeks ago

This is possible already in the python standalone module. gdsfactory/kfactory use this to generate screenshots (also stuff like kweb use this for sending updates)

Plotting code is here https://github.com/gdsfactory/kfactory/blob/main/src/kfactory/widgets/interactive.py#L63

But essentially it boils down to this:

LayoutView.get_screenshot_pixels().to_png_data()

klayoutmatthias commented 2 weeks ago

Yes, correct.

Actually, the reason why the Application object is required is QImage. For some reason it needs a QApplication object. To mitigate this, I have introducted the "PixelBuffer" class. "LayoutView#get_pixels" works like "get_image", but returns a PixelBuffer instead of QImage. That is why this version is available also for the Python module and does not need Qt.

Among other things, a PixelBuffer can be written png and also be converted to a PNG bytestream which makes it perfect for server-side image generation. The "kweb" module makes use of that feature to implement a browser-based interface (https://pypi.org/project/kweb/). All of that does not need an Application object.

Regarding @srooks10's question if there is a more lightweight alternative: you can build KLayout without Qt (use build.sh -without-qt). This gives you a binary without a user interface - only supporting "-b" - but does not require Qt. You will have very few dependencies then (curl, zlib, expat, ruby, python).

In my case (Ubuntu 24), this build creates binaries that bundle into a tar.gz of 17MB, compared to 61MB deb in the full version, not counting the Qt libraries which probably also need to be installed.

Matthias

klayoutmatthias commented 2 weeks ago

@sebastian-goeldi was quicker than me - he answered while I was still typing :)

klayoutmatthias commented 2 weeks ago

But I did a build to check the binaries' size too :)