johannesnoordanus / svg2gcode

MIT License
5 stars 2 forks source link

Wrong dimmensions when using `--pixelsize` #10

Closed fdev31 closed 1 year ago

fdev31 commented 1 year ago

I was recently mostly using test patterns, didn't check the size... I just printed some picture which was exactly 3cm tall, it turned into 1.8cm after engraving. The ratio is exactly 0.6 which is my pixel size ratio (0.06/0.1)...

Tested on image only.

Looks like it's not related to the pixel size, I just did some test with image2gcode and it works. Maybe that's because It was a very big image which I had to resize in inkscape ? Also the bounding box seemed strange (square while it is a rectangular image).

fdev31 commented 1 year ago

I'm not sure about this one. The SD card I'm using stopped working little after I had this problem. At the moment I can't test and probably for the next few weeks... :disappointed: So take it with a pinch of salt :smile:

fdev31 commented 1 year ago

Ok, I think I found what I may have experienced: scaling images isn't supported ? I didn't rebase the latest version yet (using settings branch).

johannesnoordanus commented 1 year ago

Yes it is supported. The transformation engine is generic and works for all points in the SVG. The image points are all transformed. I did several tests with ‘complicated’ images (drawing and images combined) and it works like a charm! I also added rotation (the files are not in the repository yet, only locally, but it is already available on pypi!) and this too works like it should.

johannesnoordanus commented 1 year ago

I was recently mostly using test patterns, didn't check the size... I just printed some picture which was exactly 3cm tall, it turned into 1.8cm after engraving. The ratio is exactly 0.6 which is my pixel size ratio (0.06/0.1)...

Tested on image only.

Ok, as I mentioned, there is no special case for images, all points are transformed equally! I did several tests and it works. I use gcode2image to check the result gcode file. ‘gcode2image —showimage —grid —flip —showOrigin file.gc file.png’ shows the exact positioning and size of all gcode ‘objects’.

fdev31 commented 1 year ago

Ok, was it a recent addition ? I'll update & give it a try, else I'll attach the file here... can it be related to the 0.06 pixelsize ? I again did a test, this time with png / completely different, also got something 0.6 of the desired size... (6cm instead of 10).

johannesnoordanus commented 1 year ago

I was recently mostly using test patterns, didn't check the size... I just printed some picture which was exactly 3cm tall, it turned into 1.8cm after engraving. The ratio is exactly 0.6 which is my pixel size ratio (0.06/0.1)...

I updated gcode2image because the grid shown (option --grid) did not scale with resolution. I added option --resolution to gcode2image (version 2.2.0) to set the image resolution, but note that that is independent of the size of the images!

fdev31 commented 1 year ago

I confirm the issue, and now I'm 100% certain it's related to the --pixelsize. The resulting images are scaled by a ratio of "pixelsize / 0.1". To get things properly sized I need to scale it by 1.6666666666666667.

fdev31 commented 1 year ago

Additional notes:

johannesnoordanus commented 1 year ago

I confirm the issue, and now I'm 100% certain it's related to the --pixelsize. The resulting images are scaled by a ratio of "pixelsize / 0.1". To get things properly sized I need to scale it by 1.6666666666666667.

Ok, I'll look into that. Code inspection did not reveal this, but maybe I missed that. But my question is, what version of svg2gcode are you using? It should be svg2gcode version 2.4.0! What svg2gcode options do you set when things go 'wrong'?

johannesnoordanus commented 1 year ago
  • reported bounding box info exposes the issue by showing different values with different pixelsize

Ok, that is a good point, that should not happen.

If you draw a path around the image(s), do you still have the same problem?

fdev31 commented 1 year ago

To confirm the issue, I used the latest version (using pip install -U on a venv): ❯ svg2gcode --version svg2gcode 2.4.0

Message ID: @.***>

fdev31 commented 1 year ago

Paths aren't concerned by the issue, and since it makes images smaller, the bounding box will not change if I set a path around an image (since the image will be "inside" the path, which is correct).

For some tests I only used --pixelsize argument with value 0.06, no other argument, since the bug is visible from the gcode I didn't need to set the laser values & test for real.

johannesnoordanus commented 1 year ago

Ok, did some tests just now, and I can confirm the issue. I'll fix this.

fdev31 commented 1 year ago

Awesome, thanks!

Le jeu. 24 août 2023 à 12:45, johannesnoordanus @.***> a écrit :

Ok, did some tests just now, and I can confirm the issue. I'll fix this.

— Reply to this email directly, view it on GitHub https://github.com/johannesnoordanus/svg2gcode/issues/10#issuecomment-1691445095, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAB2IHW6RKMXA3LCQR6UDVLXW4WFLANCNFSM6AAAAAA3S4OJZE . You are receiving this because you authored the thread.Message ID: @.***>

johannesnoordanus commented 1 year ago

Ok, fixed it in version 2.5.0 of svg2gcode and version 2.3 of image2gcode. Different fixes by the way!

fdev31 commented 1 year ago

Now it's consistent ! But still some problem seems to remain:

Using a tiny path in SVG which cover the whole document, I can export it to PNG (the whole page) and compare the results of svg2gcode vs image2gcode (since the DPI is set properly it should result in the exact same dimensions).

Document is 10cm x 3cm and the content almost fills it. Using svg2gcode:

; Boundingbox: (X5.967950,Y2.185769):(X94.032053,Y27.814232)
; Bbox center: (X50.000001,Y15.000001)

which looks absolutely fine. But using image2gcode with the exported png is surprising: Area: 177.6mm X 53.4mm (XY) while it should show the exact same values.

fdev31 commented 1 year ago

Doing more tests, it looks like something have changed in the linked images loading, it's not working well anymore and fails loading in some situations (when the path is relative to the svg image).

Regarding the images sizes, it looks really broken now, not even related to the pixelsize, dropping the png image in the svg document so it perfectly overlaps the path gives even more funny results:

Boundingbox: (X0,Y2):(X135.561480,Y74.576196)
johannesnoordanus commented 1 year ago

Now it's consistent ! But still some problem seems to remain:

Using a tiny path in SVG which cover the whole document, I can export it to PNG (the whole page) and compare the results of svg2gcode vs image2gcode (since the DPI is set properly it should result in the exact same dimensions).

Document is 10cm x 3cm and the content almost fills it. Using svg2gcode:

; Boundingbox: (X5.967950,Y2.185769):(X94.032053,Y27.814232)
; Bbox center: (X50.000001,Y15.000001)

which looks absolutely fine. But using image2gcode with the exported png is surprising: Area: 177.6mm X 53.4mm (XY) while it should show the exact same values.

Looks like a factor 2? What DPI setting?

svg2gcode translation is based on SVG user units that are abstract (e.g. not mm, inch etc.). The mapping is set by document settings (Inkscape) and should be 'mm' (that shows on screen for your document and object properties). Also 1 mm should correspond to 1 user unit. See the Document Properties tab in Inkscape (look at the scale factor). svg2gcode 'sees' objects in user units, and expect a 'correct' mapping.

    # Note on 'user-units':
    #   - viewBox values are in 'user-units'
    #   - drawings, like the ones described by 'svg path', are done in user space (coordinates are in user-units).
    #   - viewport values are not necessarily in user-units, but have a fixed mapping to user-units
    #   - Inkscape defaults to 'user-unit' in mm: 1 user-unit is 1 mm).

So that is the size bit.

svg2gcode chooses a default resolution of 254 DPI (it could be anything because resolution does not effect size, but this seems reasonable because of laser machine resolutions). this means 10 pixels per mm. Of course, you can set this now via --pixelsize which is used as a factor (1/pixelsize) to set the correct number of pixels for the image.

    # set image resolution based on a DPI of 254 (10 pixels per mm) and given pixelsize

So that is the resolution bit.

Maybe this all is clear to you, but I like to make sure you know.

fdev31 commented 1 year ago

Looks like a factor 2?

Not to me, this time I don't get what's happening, it's not as obvious as the pixelsize bug.

What DPI setting?

Good guess, indeed it looks like DPI is completely ignored so the number of pixels is the only thing considered by image2gcode (or just not applied properly), the image size is proportional to the DPI (while it shouldn't).

Interestingly (or not), I can't get the same thing with svg2gcode at the moment, doing a test which I thought was similar as the previous one I did. Maybe there was something wrong in my test like something I didn't see in the viewport...

About the resolution, it looks a little low, but now I understand some results I got with image dithering not working as expected. Most lasers have a better resolution than this (0.08 is the standard), mine have a 0.06 spot size (~ 423dpi) so almost twice the internal resolution of this app. I am not fully understanding why you need to rescale images internally though ^^

johannesnoordanus commented 1 year ago

Doing more tests, it looks like something have changed in the linked images loading, it's not working well anymore and fails loading in some situations (when the path is relative to the svg image).

Ok, (well not ok), do you have the file name strings from the sgv's (field 'xlink:href') that do not work? Because that should not happen.

johannesnoordanus commented 1 year ago

I found a nasty error: bounding box info wasn't initialised properly (svg2gcode). This might explain some of the problems you mention. I have a fix and an update, but that will be tomorrow.

johannesnoordanus commented 1 year ago

Updated image2gcode to version 2.4.0. This is a roll back with added comment and clarification. Updated the README to make things clear. Updated gcode2image to version 2.3.0. This is a change of option --showorigin (no capitals now).

Images conversion to gcode and the inverse work correct (now) and give the same dimensions (but see the README).

svg2gcode update (2.6.0) is nearly there, but I need to do some conversion checks.

johannesnoordanus commented 1 year ago

Not to me, this time I don't get what's happening, it's not as obvious as the pixelsize bug.

I think this was due to the bounding box initialisation problem I mentioned. This could wreak havoc , because the order of 'images' and 'path' objects within the SVG file determined a correct or faulty initialisation. Anyway, I fixed that and subsequent tests reveal correct results, even with a pixelsize of .06 mm.

What DPI setting?

Good guess, indeed it looks like DPI is completely ignored so the number of pixels is the only thing considered by image2gcode (or just not applied properly), the image size is proportional to the DPI (while it shouldn't).

That is right, image2gcode produces images (gcode) of pixelsize * number of pixels (both dimensions). I just made it that way. svg2gcode has a destination size (in mm) for each image within the SVG drawing, and calculates the number of pixels needed for the specific pixelsize. The source image is scaled accordingly to make the correct image information available for the conversion function to operate correctly.

But I could do that with image2gcode, and in fact, I did. So now image2gcode has option '--size width height', that sets target (gcode output) width and height in mm. This is available in version 2.5.1. I also added option '--center', which places the origin at the center of the image (gcode output). Several test with image2gcode and gcode2image revealed the correct sizes.

Interestingly (or not), I can't get the same thing with svg2gcode at the moment, doing a test which I thought was similar as the previous one I did. Maybe there was something wrong in my test like something I didn't see in the viewport...

See my comment above about the bounding box error.

About the resolution, it looks a little low, but now I understand some results I got with image dithering not working as expected. Most lasers have a better resolution than this (0.08 is the standard), mine have a 0.06 spot size (~ 423dpi) so almost twice the internal resolution of this app. I am not fully understanding why you need to rescale images internally though ^^

Nice that the laser has such a small spot size!. I have to do with .08 mm^2. But if you set the pixelsize on 0.06 svg2gcode (and image2gcode) generate a result with exactly that pixelsize (in gcode). So results should be spot on. Image dithering is not needed at all and even unwelcome in my opinion.

Image source resolution is important though, because if the resolution is to low for a pixelsize of .06 (for example) the image will be upsampled, and that will create image artefacts that might be visible. So I alway choose images that have a source resolution that is as large or better than required (downsampling does generates artefacts, but much less visible (in my experience)).

Anyway, svg2gcode version 2.6.2 is out and incorporates the bounding box fix and some other things. One of which is a new option --selfcenter, which generates 2 passes, one to determine the bounding box, two to set the origin at the center. Note that gcode2image is updated to version 2.3.0

johannesnoordanus commented 1 year ago

I would like to close this issue because the issue is solved.

fdev31 commented 1 year ago

Can't have time to test now, but according to what you said I think we can consider it closed :)

As a side note, I tested lightburn and it "just works", including some interesting things which are really useful:

On the other hand I'm very unhappy with their USB / connection flow / UI / code which works surprisingly poorly (at least on linux).

johannesnoordanus commented 1 year ago

Can't have time to test now, but according to what you said I think we can consider it closed :)

Ok, I'll close it As a side note, I tested lightburn and it "just works", including some interesting things which are really useful:

  • configurable dithering, made internally (meaning it will always be optimal resolution) - I also found dithering not so useful using your code, but there it works very well... maybe because of the internal resolution ? It seems to allow "faking" better dynamic range and made drastic improvements for some test images I had

I know light burn, it is the reason I started this project. Dithering is something you can do beforehand using image processing software, or even Inkscape. There is no 'internal' resolution in the code I use, I made an error updating image2gcode in this regard and correct that later on. The resolutions is entirely your choice, but takes SVG requirements for image size into account. Image2gcode has a --size option to also set such a requirement, but pixelsize of the result image (gcode) is alway exactly what you define. So maybe your test regarding dithering where not complete. I know dithering effects will work because all pixels are translated one on one. The only thing that can wreck havoc is up and downsampling possibly happening because of an image resize. Inkscape is a much (much) better and universal (generic) approach than the editor of lightburn. And you can control image resizing and generate dithering using Inkscape.

That was/is the solution I was thinking off. But I had no time to verify the issue myself. But I will incorporate that in the near future when needed.

On the other hand I'm very unhappy with their USB / connection flow / UI / code which works surprisingly poorly (at least on linux).

This is the same on Mac, but after a while it will grow on you. I tested it for a month and found that it works. But I don't like the paying bit and the lack of a good editor (Inkscape is the way to go in my opinion). I also wanted much more control over the emitted gcode and what 'is going on'. I (we) now have that with the tools that are created by me. And I am happy with the feedback you gave/give because that makes things a lot better defined and bug free.

If you are looking for other tools that work, try LaserWeb. The user interfaces is a bit difficult to grasp at first, but it does work with SVG documents and is able to 'fill' shapes and generate gcode for it! It also has a great gcode visualiser which is really precise. I use that to check my gcode for example.

Edit: note that I did not get LaserWeb to work on my Arm based board (running Manjaro) yet. I currently use it on the Mac only. But it is a web app so it should be possible.