Skip to content

Rescale pixel size in svg image

Phil Duby edited this page May 15, 2021 · 3 revisions

Peter Van Epp wrote a tutorial in the Forum on how to Rescale a svg using Inkscape.

Here is another way to rescale a drawing. Actually this is NOT 'rescaling' as such. What it does is change the number of pixels per physical unit, WITHOUT changing the actual size (in physical units) of the graphics. This works for someone willing to edit the SVG file with a text editor, and do a little math. It is a quite a bit simpler than manipulating the scale in Inkscape.

WARNING: The steps shown here work "as is" for breadboard and schematic view svg files. For PCB, additional work is needed to handle the multiple layers. Either individual (but identical) scaling wrapper elements are needed for silkscreen and copper layers, with the ungroup and regroup done one layer at a time, or the layers need to be recreated after rescaling.

Summary:

  • calculate the multiplication factor to get the viewBox from the current to desired values
  • add a wrapper group element with only scaling
  • change the viewBox to match
  • using Inkscape ungroup to propagate the scale down to the group contents
  • after the drawing is completely ungrouped, group one time and change the id to recreate the layer.

More step by step details, with reasoning.

Starting from a basic Fritzing view svg that happens to be done with 72 ppi, with a structure like:

<?xml version="1.0" encoding="UTF-8"?>
<svg
  «attributes»
  width="1.23in" height="2.34in"
  viewBox="0 0 88.56 168.48"
>
  <g id="something">
    …
  </g>
</svg>

The goal for this example, is to get the drawing to uses mils (1000 mils per inch) for pixels, so the viewBox should be "0 0 1230 2340", which is simply each of the width and height (in inches) values multipled by 1000. The direct conversion factors would be 88.56 * (1230 / 88.56) and 168.48 * (2340 / 168.48). However those might not be quite the same factor. They are here, but various (previous) manipulations of the drawing could have gotten them 'off' by a little. That multiplication factor is going to be used to scale the existing pixel coordinates in x and y, and the x and y scales MUST be the same. If they are not, ungrouping in Inkscape is going to turn circles into ellipses, which breaks the Fritzing connectors. To avoid that, calculate a single scaling factor from the sum of the x and y pixel dimensions. (1230 + 2340)/(88.56 + 168.48) = 13.888888888888891. 13.8 repeating is the factor to go from 72 ppi to mils. But that does not really matter. The calculation works whatever the original pixel size to real world units relationship happens to be. With that number, adjust the svg file, by adding 2 lines, and changing the viewBox attribute. Do not shorted, truncate, or round the calculated scale value. Let Inkscape use as much as it can handle when the ungroup steps are done.

<?xml version="1.0" encoding="UTF-8"?>
<svg
  «attributes»
  width="1.23in" height="2.34in"
  viewBox="0 0 1230 2340"
>
  <g transform="scale(13.888888888888891, 13.888888888888891)"> <!-- new line -->
  <g id="something">
    …
  </g>
  </g> <!-- new line -->
</svg>

If you display that in an image viewer, it should look exactly the same as the original. Now, open the modified svg file in Inkscape. The steps here are the same as (or very close) to what Peter described, without the scale adjustments and fixes for circles. Peter has an adjustment to the tutorial, which will avoid the issue with circles.

  • Select the whole drawing <ctrl>+a (or just click the wrapper group)
  • ungroup (object ungroup = <shift>+<ctrl>+g) multiple times. Depending on how "clean" the original svg file was, that could need a couple of ungroups, or 20+. Extra ungroup operations do not hurt anything. Keep repeating until Inkscape tells you (middle of the bottom status bar) that there are "No groups to ungroup in the selection".
  • group (<ctrl>+g) one time
    • before creating the group (layer) is also an opportunity to tweak a few things, like resize page to selection and adjust the starting coordinates to 0,0
  • change the id for the new group to match the layer that was lost during the ungroup steps
    • this can be done here, or by editing the svg file with a text editor after saving and exiting from Inkscape
  • save the drawing using whatever Inkscape option you prefer
  • the saved drawing now has 1 pixel = 1 mil.
  • cleanup anything that Inkscape did, that does not work for Fritzing (px units for font size)

Extra notes:

Drawing Units:

It is 'easy' to manually change between "mm" and "in" units in an svg file. All that is needed is to change the "height" and "width" attribute values in the main svg element. The viewBox and drawing content do not need to be touched. For both attributes, change "«n»in" to "«25.4*n»mm", or "«n»mm" to "«n/25.4»in". Round the calculated values to something 'reasonable'.

This is easy to do in Inkscape too, but then you need to go through the process of getting Inkscape to save a file that works well with Fritzing, and cleanup some things that Inkscape always gets wrong (as far as Fritzing is concerned).

Clone this wiki locally