Here is some code. I hope the comments are self-explaining:
# Illustration of how to use Region.rasterize
# This code takes the shapes from layer 66/20
# of the current cell and rasterizes a region
# 0,1 .. 80,210 (µm) with a resultion of 100nm
cell = pya.CellView.active().cell
ly = cell.layout()
layer = ly.layer(66, 20)
# box to render in µm
box_to_render = pya.DBox(0, 10, 80, 210)
# pixel size in µm
pixel_size = pya.DVector(0.1, 0.1)
# creates a Region object with the shapes to render
# using "box_to_render" to confine the search for shapes
shapes_to_render = pya.Region(cell.begin_shapes_rec_touching(layer, box_to_render))
# Performs the rasterization
# The result will be a 2d array in "areas"
# where the value is the covered area per pixel
# in square database units.
um_to_dbu = pya.DCplxTrans(ly.dbu).inverted()
box_to_render_dbu = um_to_dbu * box_to_render
pixel_size_dbu = um_to_dbu * pixel_size
nx = round(box_to_render_dbu.width() / pixel_size_dbu.x)
ny = round(box_to_render_dbu.height() / pixel_size_dbu.y)
# gives the areas covered in units of square data base units
# (see comments below about "merged")
areas = shapes_to_render.merged().rasterize(box_to_render_dbu.p1, pixel_size_dbu, nx, ny)
# for illustration, write as grayscale image
pixels = pya.PixelBuffer(len(areas[0]), len(areas))
amax = float(pixel_size_dbu.x * pixel_size_dbu.y)
y = len(areas)
for arow in areas:
x = 0
y -= 1
for a in arow:
value = int(round(255.0 * a / amax))
rgb = value * 0x10101
pixels.set_pixel(x, y, rgb)
x += 1
pixels.write_png("/tmp/discussion_2630.png")
A small test case of mine rendered a 800x2000 pixel image in less than a second:
There is a caveat: the rasterize function will count overlapping shapes twice, hence the area may be larger than the maximum expected area. The "merged()" method will take care of that, by computing the merged polygons which are free of overlaps. If you pick a too complex region, for example a SRAM block, this method may need a lot of memory.
If the box to render is small, there is little overhead however.
Thank you very much for your reply, I really appreciate it. If I need to render multiple layers, how can I do that? Perhaps the rasterized result can be converted to a grayscale image using the following code?
@Matthias@leo_cy
Hello, Happy New Year!
I used the rasterize() function to convert GDS to BMP. My goal is to split the GDS image into fields of 408.24 [um], with the output image being 1080x1080, and achieving a resolution of 0.378 microns per pixel.
However... almost all areas (except for two specific points I marked) became two pixels wide instead of the one-pixel width I set. I’m currently working on finding the cause of this issue.
Heres is my python ,GDS and Bmp Output.
Comments
Here is some code. I hope the comments are self-explaining:
A small test case of mine rendered a 800x2000 pixel image in less than a second:
There is a caveat: the rasterize function will count overlapping shapes twice, hence the area may be larger than the maximum expected area. The "merged()" method will take care of that, by computing the merged polygons which are free of overlaps. If you pick a too complex region, for example a SRAM block, this method may need a lot of memory.
If the box to render is small, there is little overhead however.
Thank you very much for your reply, I really appreciate it. If I need to render multiple layers, how can I do that? Perhaps the rasterized result can be converted to a grayscale image using the following code?
Maybe, I don't know what "cv2" is. But I think basically the same happens than in my sample. But more efficient I guess.
I you want to render multiple layers, you just need a loop. In my sample case, this line gives the layer to render:
So you can call the procedure below with different values of "layer" and different output files of course.
Matthias
Hi Matthias, thanks for your response. I'm trying to merge multiple layers with the following code, not sure if it's okay?
Yes, I think that's okay.
You can skip the first merge here:
because the final "merge" before "rasterize" will do it anyway.
Matthias
Okay, thank you very much.
@Matthias @leo_cy
Hello, Happy New Year!
I used the rasterize() function to convert GDS to BMP. My goal is to split the GDS image into fields of 408.24 [um], with the output image being 1080x1080, and achieving a resolution of 0.378 microns per pixel.
However... almost all areas (except for two specific points I marked) became two pixels wide instead of the one-pixel width I set. I’m currently working on finding the cause of this issue.
Heres is my python ,GDS and Bmp Output.
Perhaps the parameters of your function are set incorrectly? Maybe you can try 0.378。pixel_size = pya.DVector(0.378, 0.378)
@leo_cy Yes,I tried.
box_to_render = pya.DBox(0, 0, 408.24,408.24)
aligned_origin = pya.Point(
round(box_to_render.p1.x / 0.378) * 0.378,
round(box_to_render.p1.y / 0.378) * 0.378
)
pixel_size = pya.DVector(0.378,0.378)
But Still.....don't work. 0.378um Convert into 2px (I hope is 1px)
Here is my picture and Python Script