the image import feature is intended for visualization purposes, that's why no conversion to layout is provided currently.
It is possible to write a Ruby script that extracts information from the images and creates layout from that. The method of extracting layout depends on the application you have. For example, it would be possible to extract a gray level contour as a polygon, although that's more demanding on the algorithmic side.
I'm just looking for a nice method to convert images to gds2 in order to generate Logos for ICs. The image import feature of Klayout looks very good as it is possible to define the pixel size in microns. This is important because the logos shouldn't violate certain design rules.
The only thing which I need in addition is to extract 2 or 3 different colours as polygons or rectangles.
I prepared a sample script that demonstrates how to convert an image to layout.
To install the script, copy the code below to a file with a suffix .rbm, i.e. "image2gds.rbm" into
the installation directory (that is where the klayout executable is).
This script will create a new menu entry in the "Tools" menu: "Image channes to layers".
The function will take the pixel data of all images loaded and convert each pixel into a rectangle in
predefined layers, one per color channel. Each pixel is converted into a rectangle when the respective color value in that
channel is above 50%. Three layers can be specified whose layer and datatype are hard coded in
the "gds2_layers" array around line 17. Currently, layers 1, 2 and 3 are used for red, green and blue
channels respectively. Datatype is 0.
The script should be regarded as an example. I hope I added enough comments to enable you to adjust
the script to your needs.
Best regards,
Matthias
class MenuAction < RBA::Action
def initialize( title, shortcut, &action )
self.title = title
self.shortcut = shortcut
@action = action
end
def triggered
@action.call( self )
end
private
@action
end
$image2gds_handler = MenuAction.new( "Image channels to layers", "" ) do
# Defines the GDS2 layers where the three channels go.
gds2_layers = [
RBA::LayerInfo.new( 1, 0 ), # Red channel (layer, datatype)
RBA::LayerInfo.new( 2, 0 ), # Green channe (layer, datatype)
RBA::LayerInfo.new( 3, 0 ), # Blue channe (layer, datatype)
]
app = RBA::Application.instance
mw = app.main_window
lv = mw.current_view
if lv == nil
raise "No view selected"
end
cv = lv.active_cellview
if !cv.is_valid?
raise "No cell or no layout found"
end
# Create the layers if they do not exist already.
# Prepare a vector (layers) which contains the layer indices for the relevant layers.
layers = []
gds2_layers.each do |l|
layer=-1
cv.layout.layer_indices.each do |li|
if cv.layout.get_info(li).is_equivalent?(l)
layer = li
break
end
end
if layer<0
# layer does not exist yet: create a new layer (both in the layout and the layer list)
layer = cv.layout.insert_layer(l)
lp = RBA::LayerPropertiesNode.new
lp.source_layer = l.layer
lp.source_datatype = l.datatype
lv.init_layer_properties(lp)
lv.insert_layer(lv.end_layers, lp)
end
layers.push(layer)
end
# This call is important to keep the layer list consistent when
# layers have been added or removed:
lv.update_content
# Prepare an array of all images in the view
images = []
lv.each_image { |i| images.push(i) }
# The database unit
dbu = cv.layout.dbu
if images.size > 0
# start transaction for "undo"
lv.transaction( "Image channels to RGB" )
# iterate over all images
images.each do |image|
# This transformation will transform a pixel to the target location of the pixel in the layout
trans = RBA::ICplxTrans.from_dtrans(RBA::DCplxTrans.new(1 / dbu) * image.trans * RBA::DCplxTrans.new(dbu))
# The dimension of one pixel
pw = image.pixel_width / dbu
ph = image.pixel_height / dbu
# iterate over all channels
(0..(layers.size-1)).each do |c|
# That is where the shapes go
shapes = cv.cell.shapes(layers [c])
# Iterate over all rows
(0..(image.height-1)).each do |y|
# Iterate over all columns
(0..(image.width-1)).each do |x|
# Use each channel for a different layer
# d>0.5 selects all pixels with a level >50% in that channel
d = image.get_pixel(x, y, c)
if d>0.5
# Create a polygon corresponding to one pixel
p1 = RBA::DPoint.new(x * pw, y * ph)
p2 = RBA::DPoint.new((x + 1) * pw, (y + 1) * ph)
dbox = RBA::DBox.new(p1, p2)
box = RBA::Box.from_dbox(dbox)
poly = RBA::Polygon.new(box)
shapes.insert(poly.transformed_cplx(trans))
end
end
end
end
end
# commit transaction
lv.commit
end
end
app = RBA::Application.instance
mw = app.main_window
menu = mw.menu
menu.insert_separator("tools_menu.end", "name")
menu.insert_item("tools_menu.end", "image2gds", $image2gds_handler)
I hope that script serves as a preliminary solution.
@Jay: the problem with the .rbm files may be connected with the shell or system you are using. I am also not able to reproduce it on Ubuntu and Windows. However I am interested in feedback from other platforms.
I am using klayout on CentOS 4.7 and if I put the .rbm script in the directory where I start klayout, it works but putting the .rbm script in the same location as klayout binary doesn't work.
I tried to set also RUBYLIB and RUBYPATH w/ the directory containing .rbm files but no changes, seem not to be used.
KLayout derives the installation path form the $0 argument. I learned that shells behave differently and for some shells the absolute path cannot be derived from that argument.
Currently, one workaround is to start KLayout with the full path, i.e.
/use/bin/klayout ...
Maybe you can set an alias for this command, so it's less effort typing.
For the next release I plan to add a more consistent ruby module installation scheme which should avoid those problems.
the idea is to first add an image with "Edit/Add Image", adjust the position and size and then let the script convert that image (or the images) to GDS geometry.
there are numerous vectorizers out on the net. If you need a CAD format, you can try online image to DXF translators (google for "image to dxf converter online").
Your script to import an image to gds looks very good! However, do I need to add this script to the source file, and compile klayout myself? I installed the binary version on my mac pro. Could you possible to run it with the binary version?
The best way I've found is to convert a raster image (eg. PNG, JPG) into vector (PDF) and then into DXF. I found InkScape was the best tool for this - although on MacOS you also have to install XQuartz (an X-windows system) to use it.
To convert your raster image into PDF, I use PoTrace (a command-line tool that is also built into InkScape), or just do it through InkScape itself.
Like this tutorial: http://www.wikihow.com/Convert-Raster-to-Vector
-- see the 2nd "inkscape" method
POTrace (command-line tool): http://potrace.sourceforge.net
Then convert the PDF into DXF - InkScape can also save into DXF (Autocad R14 compatible). I was then able to open this in KLayout (or AutoCad)! Of course, then you can save it as GDSii or any other format KLayout supports.
Comments
Hi Joe,
the image import feature is intended for visualization purposes, that's why no conversion to layout is provided currently.
It is possible to write a Ruby script that extracts information from the images and creates layout from that. The method of extracting layout depends on the application you have. For example, it would be possible to extract a gray level contour as a polygon, although that's more demanding on the algorithmic side.
What exactly are you looking for?
Best regards,
Matthias
I'm just looking for a nice method to convert images to gds2 in order to generate Logos for ICs. The image import feature of Klayout looks very good as it is possible to define the pixel size in microns. This is important because the logos shouldn't violate certain design rules.
The only thing which I need in addition is to extract 2 or 3 different colours as polygons or rectangles.
Best regards,
Joe
Hi Joe,
I prepared a sample script that demonstrates how to convert an image to layout.
To install the script, copy the code below to a file with a suffix .rbm, i.e. "image2gds.rbm" into
the installation directory (that is where the klayout executable is).
This script will create a new menu entry in the "Tools" menu: "Image channes to layers".
The function will take the pixel data of all images loaded and convert each pixel into a rectangle in
predefined layers, one per color channel. Each pixel is converted into a rectangle when the respective color value in that
channel is above 50%. Three layers can be specified whose layer and datatype are hard coded in
the "gds2_layers" array around line 17. Currently, layers 1, 2 and 3 are used for red, green and blue
channels respectively. Datatype is 0.
The script should be regarded as an example. I hope I added enough comments to enable you to adjust
the script to your needs.
Best regards,
Matthias
Putting the .rbm script in the same location as klayout binary doesn't work. If I put it in the current working directory, it works.
many thanks for your script.
It works pretty fine and it is exactly what I was looking for!
Might be a good idea to include a similar function in a new release of KLayout.
@Jay: It works also in the directory where the KLayout binary is (I'm using the windows version of KLayout at the moment).
Best regards,
Joe
Hi,
I hope that script serves as a preliminary solution.
@Jay: the problem with the .rbm files may be connected with the shell or system you are using. I am also not able to reproduce it on Ubuntu and Windows. However I am interested in feedback from other platforms.
Best regards,
Matthias
I am using klayout on CentOS 4.7 and if I put the .rbm script in the directory where I start klayout, it works but putting the .rbm script in the same location as klayout binary doesn't work.
I tried to set also RUBYLIB and RUBYPATH w/ the directory containing .rbm files but no changes, seem not to be used.
Best Regards,
Joaquim
Hi Joaquim,
KLayout derives the installation path form the $0 argument. I learned that shells behave differently and for some shells the absolute path cannot be derived from that argument.
Currently, one workaround is to start KLayout with the full path, i.e.
Maybe you can set an alias for this command, so it's less effort typing.
For the next release I plan to add a more consistent ruby module installation scheme which should avoid those problems.
Best regards,
Matthias
Hi Joaquim,
in the lastest version 0.19.3 you can set an environment variable $KLAYOUT_PATH which points to the directory containing the .rbm files.
Best regards,
Matthias
it works fine. Thanks.
Best Regards,
Joaquim
Please, can you give more details on its usage ?
Thanks,
OkGuy
Hi,
the idea is to first add an image with "Edit/Add Image", adjust the position and size and then let the script convert that image (or the images) to GDS geometry.
Is that what you are looking for?
Matthias
I'm interesed in converting an image to a polygon, by extracting the gray level as commented above.
Some one to help me?
Thanks
Hi,
there are numerous vectorizers out on the net. If you need a CAD format, you can try online image to DXF translators (google for "image to dxf converter online").
Matthias
can you please past your code that you have modified .
Thank you
Your script to import an image to gds looks very good! However, do I need to add this script to the source file, and compile klayout myself? I installed the binary version on my mac pro. Could you possible to run it with the binary version?
Thank you
Hello,
no, no need to recompile. You'll find a lot of documentation about using and writing scripts here: http://www.klayout.de/doc/programming/index.html.
Matthias
To convert your raster image into PDF, I use PoTrace (a command-line tool that is also built into InkScape), or just do it through InkScape itself.
Like this tutorial: http://www.wikihow.com/Convert-Raster-to-Vector
-- see the 2nd "inkscape" method
POTrace (command-line tool): http://potrace.sourceforge.net
Then convert the PDF into DXF - InkScape can also save into DXF (Autocad R14 compatible). I was then able to open this in KLayout (or AutoCad)! Of course, then you can save it as GDSii or any other format KLayout supports.