It looks like you're new here. If you want to get involved, click one of these buttons!
When using Klayout's API save_image_with_options to save a DXF file as a BMP image, 0.4-micron lines placed in different positions sometimes appear as 1 pixel, while others become 2 or 3 pixels. How can this issue be resolved?
Here is DxfFile(jpeg format,Dxf froamt is not surpported),And Bmp as result.
Thanks a lot
Comments
Can you attach the
abc.dxf
file by zipping it toabc.dxf.zip
?Also, please provide more details on using the
save_image_with_options()
function, including the clip window geometry.Ok , I upload dxfFile,bmpFile and python script using save_image_with_options().Thanks for your help.
Ok , I upload dxfFile,bmpFile and python script using save_image_with_options().Thanks for your help.
Thank you for sharing the DXF file.
Before going into the details of the code, I checked the DXF file itself.
See the six images below.
Observations and Questions:
1. Some Polylines are not converted to Polygons but treated as zero-width Paths.
2. Some Paths are overlapping Polygons. Is this design intentional? Therefore, is the file named
Overlay.dxf
?3. What is the rough chip size? About 2mm x 2mm?
[Edit] I found a problem: My DXF Reader Option was inappropriate; it needed a scaling factor of x1000. Now, I can proceed.
To be continued.
Hi @Flyingmyd,
def convert_gds_to_png(input_file, output_file, dbox_xmin, dbox_ymin, dbox_xmax, dbox_ymax, width, height):
? Or externally converted GDS2 file?conversion_log.txt
seems to have the actual clipping geometries.Cont.
With more observations, I understood as follows:
1. the output image size is 1080 x 1080 [pix]
2. the top cell's bounding box is 2041.2 [um] square
3. if the above bounding box is split into 5x5 regions, each covers 408.24 [um] square region
4. 408.24 [um] / 1080 [pix] ---> 0.378 [um/pix], which is nearly equal to the critical dimension (0.4 [um])
5. on the other hand, (most of) the coordinates are not on the 400 [nm] grid (see the image below)
6. therefore, when digitizing to a bitmap, rounding off errors occur, which is the route cause of the uneven pixel distribution
To be continued.
Cont.
As I observed above, your bitmap resolution (DPI) is too small.
So, I remade your Python script (see the attached ZIP file).
The wrapper batch (RunKlayoutDxf2Png.bat) script is no longer required.
I tested it on Linux Mint 20.3, Windows 11, and Mac.
The command line parameters are as follows (modify it as you like).
My idea includes:
1. Instead of explicitly providing the clipping window from outside, determine it internally based on...
2. (a) the cell size, (b) the critical dimension, (c) how many pixels are allocated to the CD, and
3. (d) the target (not fixed but variable) output canvas size
Test Run
Kazzz-S
Hi @sekigawa,
thanks for this elaborate analysis, as usual!
There is a related discussion here: https://www.klayout.de/forum/discussion/2630/how-to-use-the-rasterize-function-to-render-a-specified-area-of-a-gds-file#latest
I have repeatedly made a statement regarding the use of "save_image" for manufacturing purposes. This function is meant for visualization, so it does not care about one pixel more or less. There is a lot of optimization involved, and under certain circumstances, the output maybe precise, but a little bit off things may look bad again. "save_image" is NOT intended for precision rasterization and I strongly advice against using it for generating mask data - if that is what you are trying to do.
The mentioned alternative discussion explains how to use a different approach to get precision grayscale rasterization at the cost of higher memory consumption and runtime. It uses the "rasterize" method of
Region
. Please is this feature when you need predictable and production-quality rasterization.Matthias
Cont.
The
[-b|--noborder]: no image border
option was inappropriately named and had a bug.Apologies for the inconvenience. The correct version is now:
Modified
Kazzz-S
I think it will go best for you, if the scale factors
are "round number" multiples / divisors. Can't do
"fractional pixels" so you end up "notchy" in any
conversion / resizing, unless integer multiples of
initial DBU?
Large DBU per UU will mimimize, but only round
number scaling eliminate, the "width toggling".
Like, 1000 may be good but is 1024 the magic
number? Or maybe it's 960.
@sekigawa
Happy New Year!
Thanks For you so-detailed reply.I was so busy Recently. Now I get back.
' ' '
1.Some Polylines are not converted to Polygons but treated as zero-width Paths.
Answer: Yes, this is because the DXF image was drawn in QCAD. When opened in KLayout, some polylines remain as polylines, while others are converted to paths.
2.Some Paths are overlapping Polygons. Is this design intentional? Therefore, is the file named Overlay.dxf?
Answer: This DXF design is for etching purposes, and the overlapping polygons are a design requirement.
3.What is the rough chip size? About 2mm x 2mm?
Answer: The overall size is 2.0399mm x 2.0399mm.
' ' '
Hi ! @sekigawa
With more observations, I understood as follows:
' ' '
The output image size is 1080x1080 [pix].
The top cell's bounding box is 2041.2 [um] square.
If the above bounding box is split into 5x5 regions, each covers a 408.24 [um] square region.
408.24 [um] / 1080 [pix] ---> 0.378 [um/pix], which is nearly equal to the critical dimension (0.4 [um]).
On the other hand, (most of) the coordinates are not on the 400 [nm] grid (see the image below).
Therefore, when digitizing to a bitmap, rounding errors occur, which is the root cause of the uneven pixel distribution.
' ' '
Answer: My goal is to split the DXF image into regions of 408.24[um] each, with the output image being 1080x1080. This DXF image has 5 regions, so the total size is 408.24[um] × 5. Additionally, I need to achieve 0.378 microns per pixel.
@sekigawa
' ' '
As I observed above, your bitmap resolution (DPI) is too small.
So, I remade your Python script (see the attached ZIP file).
The wrapper batch (RunKlayoutDxf2Png.bat) script is no longer required.
I tested it on Linux Mint 20.3, Windows 11, and Mac.
' ' '
Answer: Thank you for your script! You’re amazing. However, I must use the 1080x1080 split because the lower-level machine only supports 1080x1080 images. I tested your script with the 1080x1080 output, using the parameters -c=0.378 and -p=1, but I still encountered the same issue I mentioned.
After reading comments from others(https://www.klayout.de/forum/discussion/2630/how-to-use-the-rasterize-function-to-render-a-specified-area-of-a-gds-file#latest), I found that the problem lies in the improper use of the API (save_image_with_options). Some forum users mentioned in this thread that the Region rasterize API is specifically designed for rasterizing. Using the rasterize() API, I was able to achieve the same operation as save_image_with_options() (splitting the DXF image into regions of 408.24 [um], with the output image being 1080x1080).
The results with rasterize() are much better than with save_image_with_options(). 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.
Below is my Python script and the generated images:
Let me know if you need further clarification!
@Matthias
Yes, thank you for your suggestion. I used the rasterize API you recommended, and the results have significantly improved. However, some issues still remain, as detailed in my reply to Sekigawa.
@dick_freebird
Happy New Year!
Yes, I agree with you. However, I must generate 1080-pixel images. A 1080p image corresponds to a 408.24 [um] field, where a line width of 0.378 [um] corresponds to 1 pixel. I’ll try discussing with the project manager whether we can use 1000 instead.
Hi @Flyingmyd,
I think this is related to this post: https://www.klayout.de/forum/discussion/2653, right?
Please see my reply there.
Matthias