easy to convert existing SVG to mm?

so let’s not change that. simple.

2 Likes

Given that’s part of Rack’s code, it’s not up to us. Andrew has been clear that SVG files with units in millimeters is a requirement, even though modules with pixel units still work and many Fundamental and Rack component library SVG files still have units in pixels. Because he uses the word requirement, it’s possible that Rack might change in a future version in order to actually require mm unit SVG.

At least as far as the Rack component library, and any third-party library like @persy is trying to get going, I think that requiring millimeters is actually a good thing. If you start a panel layout working in millimeters and then try to pull in component graphics in order to work on layout and spacing, it becomes a chore if the component you’re pulling in has some other scaling factor (DPI). I described some trouble with this issue in this thread.

This seems to be the best way in Inkscape:

  1. Under the File menu, open “Document Properties”. On the Page tab, change both “Display units” under General and “Units” under Orientation → Custom Size to mm rather than px.
  2. Under Orientation → Custom Size, take note of the current Height in mm. In my experience, this will probably not be 128.5mm. Determine the scaling factor necessary to convert it to 128.5mm, i.e. divide 128.5 by your current height. Save this scaling factor for later.
  3. Note the current width and save it for later.
  4. Multiply the width by the scaling factor obtained in step 2. Then, divide this result by 5.08mm. In my experience, the result will probably not be a round number but rather something like “25.9609409449”. Round that to the nearest integer, then multiply that times 5.08. In this case that would be 26 * 5.08 = 132.08.
  5. Determine the scaling factor necessary to convert the original width (saved in step 3) to the correct number obtained in step 4 (eg. 132.08). Save this scaling factor for later.
  6. Change the width to the new width (eg. 132.08mm) and the height to 128.5mm.
  7. Close Document Properties. Under the Edit menu choose “Select All in All Layers” (ctrl+alt+a). Under the Object menu, select “Transform…” (shift+ctrl+m).
  8. In the Transform dialog, choose the Scale tab. Uncheck “Scale proportionally”. Uncheck “Apply to each object separately”. Enter the scaling factors that you saved earlier (Width in step 5 and Height in step 2), multiplied by 100 (to convert to percentage). Click “Apply”.
  9. Under the Object menu, select “Align and Distribute…” (shift+ctrl+a).
  10. In the Align and Distribute dialog, Select “Page” in the “Relative to:” selector.
  11. Click the button next to the “Relative to:” selector. The tooltip for this button should read “Treat selection as group”. Make sure that is enabled.
  12. Click the third button from the left in each of the first two rows: the tooltips for these buttons should read “Center on vertical axis” and “Center on horizontal axis”

That should do it. I expected to have to obtain new coordinates for component placement in the module code, especially given the ever-so-slightly different scaling factors I applied to width and height, but it seems that the existing code remains valid even if it is using pixel coordinates from the old (non-rescaled) panel. I guess this is because Rack was already scaling my graphics differently on the x and y axis and I never noticed the slight difference?

Maybe there is a faster way, in Inkscape and/or other software?

Edit: Missed multiplication, wording for clarity

2 Likes

wow, a whole 12 step program. have to say I was hoping for a command line utility that would bulk convert all my mine. But thanks!

1 Like

i’m sure someone will come up with a handy conversion script.

1 Like

Did you manage to use affinity’s exported SVG in rack using mm ? I had to convert to pixel to make it work : How to properly export from Affinity Designer to SVG

i havent tried yet. i actually just recently got affinity designer. googled around and managed to find this.

SVG uses vectors, which are decidedly not pixels.

no, but the screens on which they are displayed are. more so than millimetres, anyway. What is your point?

1 Like

The screens they are displayed on can show them at any size. Unlike pixels, which when scaled just turn into big ugly blocks. So that’s scale and vector covered. Wait until I tell you what the G stands for!

@Somegeezer - it’s not as simple as that… in fact it’s actually quite complicated.

SVGs are vector graphics, and everyone knows vectors are defined by lines (as opposed to bitmap graphics which are defined by dots/pixels) so dpi/ppi must have no relevance for SVGs right?

Unfortunately not…

SVG has a few weird quirks. While vector graphics can be displayed at any size (and retain their quality), on screen we usually want those vector graphics to display at a very specific size (such as exactly one row high in Rack) so there needs to be a way of defining it - ie a way of imposing a size on something that is essentially sizeless. One of the main issues is that different vector applications have different standards for doing so. For example, an inch is 25% longer in Inkscape than it is in Illustrator. This is because behind the scenes both programs use something called User Units to define their shortest length. User units can be thought of as similar to pixels or dots. Prior to Version 0.92 Inkscape used 90 user units of length. In version 0.92 it changed to 96 (which came from the css standard). Illustrator uses 72. These are often referred to as dpi (dots per inch) but in my opinion upi (units per inch) might be a better expression so as to distinguish them from the dpi of bitmap graphics.

If you export a 128.5mm high SVG from Illustrator it will not be the right size for Rack (it will be too small). I design my panel graphics in illustrator but then have to open, resize and save them in Inkscape 0.92 (which uses 96dpi) for them to display correctly.

I recently tried out the Inkscape v1 beta and it seems the user units might have changed again - need to look into it more but the 128.5mm high graphics I saved out from V1 were no longer the right size for Rack…

The G stands for ‘Gotcha’ btw… :wink:

2 Likes

Thanks for writing that conversion guide, I tried it and works like a charm. :ok_hand: :+1:

1 Like

wow - it sounds like a lot of steps…

Here’s a 4 step method that I’m pretty sure does exactly the same thing.

  1. Work out how many hp your module uses in VCV (count how many holes it takes up if necessary). Multiply the hp by 5.08 to get your required width in mm - so if it was 10hp it would be 50.8mm wide

  2. Open your graphic in Inkscape. Under the File menu, open “Document Properties”. On the Page tab, change both “Display units” under General and “Units” under Orientation -> Custom Size to mm rather than px. Under Orientation -> Custom Size, change height to 128.5 and change width to the mm amount calculated in step 1

  3. Back in the main document window, select everything. Click the lock icon so that width and height scale proportionately, Type the width you calculated in step 1 into the width field. Press enter. Almost done!

  4. Because the old px format and the new mm format have slightly different ratio’s, your height will probably not be exactly 128.5. It will likely be just over at something like 128.69ish. You now have 2 choices - you can either slightly squish your graphic (keep everything selected and uncheck the lock icon and type 128.5 into the height field) or simply crop the bottom 0.19ish mm off your background element such that the height now becomes 128.5. (I believe the 12 step method outlined above uses the squish method).

In fact, If you are happy with the squish method you can change Step 3 to:

  1. Back in the main document window, select everything. Make sure the lock icon is NOT checked, so that width and height DO NOT scale proportionately, Type the width you calculated in step 1 into the width field and 128.5 into the height field. Press enter. Done!

(no step 4)

3 Likes

I can’t get Affinity Designer to export mm.

You can set the document units, which allows you to work in mm inside the app. That’s very helpful.

But when it exports, it converts to px, and there seems to be no way to export in any other units.

As far as I can tell, if you set the DPI to 75 (in the New Document dialog or the Document Setup dialog), the SVG will display properly in Rack. That is, it will display properly as long as Rack remains at 15 px per hp.

Illustrator does the same (works in mm but exports in SVG in px) - it’s pretty annoying…

But takes less than 1 min to open the illustrator SVG in Inkscape, resize to mm again and save.

So, exporting to SVG from Affinity Designer driving me a bit mad - it only exports in pixels, and I am getting weary of opening Inkscape and changing units/resizing.

I’ve found that it’s actually quite easy to edit the SVG files themselves, however.

  1. Open the SVG file in a text editor.
  2. In the svg XML element, you’ll want to set viewBox to the pixel size of the SVG file (generally you can find the exact values in the first element, if you’ve added a background rect - otherwise you might want to calculate these based on the DPI). An example from a file that’s 96 DPI:

viewBox=“0 0 115.2 485.667”

  1. Set the height and width attributes to the correct output size. For example:

width=“30.48mm” height=“128.5mm”

You can copy and paste the entire line, including the svg element and attributes into any subsequent exports of the file (or other files, assuming that they’re the same size), or perhaps write a script to manipulate the files.

2 Likes

I’ve never used Python before, but I thought that it might be a good opportunity to try it to write my own script to fix these Affinity Designer files, and to hopefully automate this process. I’ve uploaded it here for anyone who wants it: GitHub - nickfeisst/ADSVGFix

You can simply add the intended width (in millimetres), height, DPI, input file, and output file.

python3 ADSVGFix.py 30.48 128.5 96 InputFile.svg OutputFile.svg

1 Like

SVG units are pixels by default, and other units imply conversion factors to the base (“user” unit). It’s cool that Inkscape has such rich SVG export, and maybe the Affinity devs would be willing to add units to SVG exports if asked on their forum (they seem to welcome ideas). But there’s no need, really, because Affinity Designer lets you set the DPI in Document Setup.

I just set mine to 75 DPI so exports match VCV Rack directly without mm2px conversions. If you really want to deal with millimeters, set it to 25.4 DPI because that’s how many millimeters are in an inch. “D” means “dots” ~= pixels ~= SVG user units ~= the raw numbers without units. “P” means “per”. “I” means “inch”, the link to physical distance units such as inches or millimeters or lightyears.

If other programs don’t like your SVGs without scripted hacks, I’d say that’s their problem for making assumptions. In that case you could calculate and set the DPI as necessary to be compatible, no scripting required.

Also, Python is bad. :snake: :-1: It’s okay to love it, though, if you do. :heart: :+1:

From what I’ve seen, however, there is a problem in rounding of the output size. For example, if I export at 25.4 DPI, then the height and width (and viewBox) of my module is rounded up to the nearest pixel. I know it’s not much, but I think, from my early tests, that it was the cause of graphical issues around the edges of my modules in Rack.

Ah, bummer that the viewbox attribute rounds up to the next integer (if your DPI is set to 25.4, this is rounding to the next millimeter; and then somewhere downstream there’s a conversion to pixels). I see that the contents like rectangles, etc. have more precision, but if you’re making use of the viewbox, yeah, might have to bug the Affinity devs for that. There’s an issue about it on their forum.

Just curious, why not go ahead and use actual pixel units for the export? I get pixel perfect results (near as I can tell) because I’m designing in millimeters while exporting in pixels (at VCV Rack’s 75 DPI). Eventually, the units end up in pixels anyway, so may as well do conversions early and save the runtime compute. What’s happening in your case is, you’re working with millimeters all the way through export, Affinity rounds for the viewbox, and then that number gets converted to pixels downstream, and it’s off because the conversion includes the rounding error.

Hope it helps, and that Affinity will fix up their export options with units and precision. For now, you can hack it or sidestep the issue by embracing pixel nature.