svg2many 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- svg2many-0.3.0/LICENSE.txt +9 -0
- svg2many-0.3.0/MANIFEST.in +5 -0
- svg2many-0.3.0/PKG-INFO +216 -0
- svg2many-0.3.0/README.md +192 -0
- svg2many-0.3.0/examples/.env +13 -0
- svg2many-0.3.0/examples/app-icons-android.json +36 -0
- svg2many-0.3.0/examples/app-icons-flutter.json +137 -0
- svg2many-0.3.0/examples/app-icons-ios.json +31 -0
- svg2many-0.3.0/examples/app-icons-macos.json +25 -0
- svg2many-0.3.0/examples/app-icons-web.json +27 -0
- svg2many-0.3.0/examples/app-icons-windows.json +26 -0
- svg2many-0.3.0/examples/assets/images/app_icon.svg +38 -0
- svg2many-0.3.0/examples/bsd.env +7 -0
- svg2many-0.3.0/examples/linux.env +7 -0
- svg2many-0.3.0/examples/macos.env +7 -0
- svg2many-0.3.0/examples/windows.env +7 -0
- svg2many-0.3.0/pyproject.toml +54 -0
- svg2many-0.3.0/setup.cfg +4 -0
- svg2many-0.3.0/src/svg2many/__init__.py +0 -0
- svg2many-0.3.0/src/svg2many/__main__.py +158 -0
- svg2many-0.3.0/src/svg2many/canvas.py +395 -0
- svg2many-0.3.0/src/svg2many/cli.py +152 -0
- svg2many-0.3.0/src/svg2many/config.py +1045 -0
- svg2many-0.3.0/src/svg2many.egg-info/PKG-INFO +216 -0
- svg2many-0.3.0/src/svg2many.egg-info/SOURCES.txt +27 -0
- svg2many-0.3.0/src/svg2many.egg-info/dependency_links.txt +1 -0
- svg2many-0.3.0/src/svg2many.egg-info/entry_points.txt +2 -0
- svg2many-0.3.0/src/svg2many.egg-info/requires.txt +7 -0
- svg2many-0.3.0/src/svg2many.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025, Alexander Iurovetski
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
svg2many-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: svg2many
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Export a single SVG to raster images of multiple resolutions
|
|
5
|
+
Author-email: Alexander Iurovetski <aiurovet@gmail.com>
|
|
6
|
+
Maintainer-email: Alexander Iurovetski <aiurovet@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/aiurovet/svg2many
|
|
9
|
+
Project-URL: Repository, https://github.com/aiurovet/svg2many.git
|
|
10
|
+
Project-URL: Documentation, https://github.com/aiurovet/svg2many/blob/main/README.md
|
|
11
|
+
Project-URL: Changelog, https://github.com/aiurovet/svg2many/blob/main/CHANGELOG.md
|
|
12
|
+
Project-URL: Issues, https://github.com/aiurovet/svg2many/issues
|
|
13
|
+
Keywords: image,svg,raster,svg2many,png,webp
|
|
14
|
+
Requires-Python: >=3.8
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE.txt
|
|
17
|
+
Requires-Dist: envara>=0.5.1
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: black; extra == "dev"
|
|
20
|
+
Requires-Dist: pytest; extra == "dev"
|
|
21
|
+
Requires-Dist: pytest-mock; extra == "dev"
|
|
22
|
+
Requires-Dist: coverage; extra == "dev"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# svg2many (C) Alexander Iurovetski 2025
|
|
26
|
+
|
|
27
|
+
## Convert an SVG file to raster images of multiple sizes, optionally splitting into background and foreground images
|
|
28
|
+
|
|
29
|
+
This application allows to produce all raster images you need (`.png`, `.webp`, or others) from a single `.svg` file. It is based on search-and-replace of the width, height and the presence of foreground and background in the content of the source file. The main idea is that since the `SVG` format is text (XML), there is a rational way to find spots where the default width, height, scale, offset and visibility should be substituted with required ones.
|
|
30
|
+
|
|
31
|
+
Dependencies: `envara`.
|
|
32
|
+
|
|
33
|
+
Pre-requisites (external dependencies):
|
|
34
|
+
|
|
35
|
+
1. An exporter from an `.svg` to a raster image file (`.png`, `.webp`, or others). This could be even your browser running in the headless mode, like _Chromium_-based one (Google Chrome, Microsoft Edge, Opera, Vivaldi, etc.) or _Firefox-based_ (Firefox, Tor, LibreWolf, etc.). The preferred exporter, however, is `rsvg-convert` from the GNOME's `librsvg2`. Depending on the OS you are running, it can be installed via `apt`, `yum`, `brew` or `chocolatey`. This exporter is faster than any headless browser or tools like `ImageMagick` or `Inkscape`, and produces images of good quality.
|
|
36
|
+
|
|
37
|
+
2. A converter from a set of raster images to `.ico` if you need to generate Windows native icons. Preferred converter is ImageMagick's `magick` (see the examples). You'll use that in the `after` attribute of configuration file.
|
|
38
|
+
|
|
39
|
+
3. There is no converter from a set of raster image files to a single `.icns` one, as the latter is deprecated by Apple (still supported for the sake of legacy though). That's why the examples for Flutter and macOS application icons do not utilise that. You are welcome to utilise that in your configuration files if you like. Please note however, that I had issues adding a 64x64 image to `.icns` using `png2icns` on Linux, and decided it is not worth the effort.
|
|
40
|
+
|
|
41
|
+
### Usage
|
|
42
|
+
|
|
43
|
+
This example can be used to generate all launcher icons for a _Flutter_ project. See also: _How Do I Use It_ at the end of this document
|
|
44
|
+
|
|
45
|
+
1. Install `svg2many` from _PyPI_
|
|
46
|
+
|
|
47
|
+
2. Create your beautiful SVG image. It is highly recommended NOT to use percentages as co-ordinates or sizes: those are getting scaled inconsistently, and so far, I have no solution that does not attempt a full-scale to parseing of an SVG. You can define a 100x100 pixel image that will essentially express the same. Example:
|
|
48
|
+
|
|
49
|
+
```xml
|
|
50
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
|
|
51
|
+
<g class="background" display="" transform="scale(1, 1) translate(0, 0)">
|
|
52
|
+
<!--Place your actual background drawing here-->
|
|
53
|
+
</g>
|
|
54
|
+
<g class="foreground" display="" transform="scale(1, 1) translate(0, 0)">
|
|
55
|
+
<!--Place your actual foreground drawing here-->
|
|
56
|
+
</g>
|
|
57
|
+
</svg>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
3. Create configuration file or take that from `examples/` in the application bundle or from the [repo's examples](https://github.com/aiurovet/svg2many/tree/main/examples)
|
|
61
|
+
|
|
62
|
+
4. Create `.env` file(s) or take those from `examples/` if you need. You can skip this step and make decision later.
|
|
63
|
+
|
|
64
|
+
5. Ensure the installation directory for `svg2many` is listed in `PATH` (or use an explicit path inside a wrapper script).
|
|
65
|
+
|
|
66
|
+
6. Run with options in any order:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
svg2many -c (your-config-file) [-r (top-dir)] [-i (input-svg)]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
All options:
|
|
73
|
+
|
|
74
|
+
- `-h, --help`
|
|
75
|
+
|
|
76
|
+
Help screen (similar to this list)
|
|
77
|
+
|
|
78
|
+
- `-c, --config CONFIG`
|
|
79
|
+
|
|
80
|
+
A file in JSON format that holds rules of conversion (see full description below). This setting is mandatory.
|
|
81
|
+
|
|
82
|
+
- `-d, --delete`
|
|
83
|
+
|
|
84
|
+
Delete all generated files, but not directories.
|
|
85
|
+
|
|
86
|
+
- `-e, --env ENV`
|
|
87
|
+
|
|
88
|
+
A text file containing lines in the `name = value` format with any number of spaces in between: `CMD_RSVG="rsvg-convert"`, then `CMD_RSVG_OUT_FILE="$CMD_RSVG --output {o}"`. It allows you to define extra environment variables to use in different configuration files. You can put there comments as well (starting with #). The application will load the content from `.env`, then `any.env`, then `posix.env` on POSIX-compatible OSes (Linux, BSD, macOS, AIX), then `bsd.env` (for FreeBSD, NetBSD, etc.), then `<OS>.env` (\<OS\> is what Python's `platform.system()` call returns, or also `macos.env` on macOS). On Windows, it would be `.env`, `windows.env`, Then, if this option is specified, that particular file. The order is important: from generic to more and more specific ones, having the later similar value overriding the earlier one. All these files will be scanned and taken from either the directory of the specified ENV or the config file's one otherwise. You do not have to have them all: the application will pick only those that are present without any warning or error that some are missing. This approach allows you to make portable (OS-independent) conversions if you need. For instance, generating images under GitHub actions, you have a luxury of automatic choice: $HOME on UNIX-like systems, $USERPROFILE on Windows, speciific paths to exporters on macOS like _"Applications/Google Chrome.app/Contents/MacOS/Google Chrome"_, and _google-chrome_ on Linux.
|
|
89
|
+
|
|
90
|
+
- `-i, --input INPUT`
|
|
91
|
+
|
|
92
|
+
An `.svg` file to convert. If INPUT is a mere - (dash), the SVG content will be read from `stdin`. Overrides `inpFile` in the configuration file.
|
|
93
|
+
|
|
94
|
+
- `-q, --quiet`
|
|
95
|
+
|
|
96
|
+
Do not print any information to the console. Mutually exclusive with `-v, --verbose`.
|
|
97
|
+
|
|
98
|
+
- `-r, --root ROOT`
|
|
99
|
+
|
|
100
|
+
Project top directory for all relative paths. Overrides `rootDir` in the configuration file.
|
|
101
|
+
|
|
102
|
+
- `-v, --verbose`
|
|
103
|
+
|
|
104
|
+
Detailed logging, primarily, to trace issues. Mutually exclusive with `-q` or `--quiet`.
|
|
105
|
+
|
|
106
|
+
The default SVG-to-raster exporter is `rsvg-convert` (to PNG), created and maintained by the GNOME project. This is the fastest and accurate way to create raster images. If you need to export to another raster image format, there is a good chance you can do that by directing the output to `stdout`, then reading into the next exporter via `stdin` (piping). See the `export` attribute in th sample configuration files.
|
|
107
|
+
|
|
108
|
+
ImageMagick and Inkscape are less performant, and also earlier, were producing images of lower quality. It looks like this area was improved. However, when I tried to use ImageMagick's `convert`, it failed. After I installed Inkscape, it suddenly started working. Please verify yourself if you would like to use it. My own preference, though, is `rsvg-convert`
|
|
109
|
+
|
|
110
|
+
Headless Chrome is another option: it supports more SVG features, but runs slower. More importantly, it is frequently broken (and it is now, as of December 2025, on Kubuntu 25.04), and the fix might take a while to come. To my memory, it was broken at least twice within a few years. The issues, in fact, were in Chromium, which is even worse, as it impacts a wider range of browsers.
|
|
111
|
+
|
|
112
|
+
Last but not least comes headless Firefox. As of December 2025, on Kubuntu 25.04, it seems to have an issue similar to Chromium. It is by far the slowest one, as it is not cached like the Chromium-based browsers. It will fail when another instance is open (e.g. you are viewing a website with it). Also, it will fail to export when SVG content is sent via stdin rather than a file, so you must use `{i}` in the command.
|
|
113
|
+
|
|
114
|
+
Please note that most of these exporters convert SVG to PNG only
|
|
115
|
+
|
|
116
|
+
## JSON Configuration File Format
|
|
117
|
+
|
|
118
|
+
### Nodes
|
|
119
|
+
|
|
120
|
+
- `$.after`, `$.targets.target.after`
|
|
121
|
+
|
|
122
|
+
Default command to run upon completion of all exports in a target (like `convert` for Windows icons). The latter overrides the former.
|
|
123
|
+
|
|
124
|
+
- `$.export`, `$.targets.target.export`
|
|
125
|
+
|
|
126
|
+
Command to export an input SVG image to an output raster image file. The latter overrides the former. Might be useful to generate `webp` icons for `Android` icons specifically.
|
|
127
|
+
|
|
128
|
+
- `$.rootDir`
|
|
129
|
+
|
|
130
|
+
Top directory for the input and output files. Can be overridden by the `-r ROOT` option with argument
|
|
131
|
+
|
|
132
|
+
- `$.inpFile`
|
|
133
|
+
|
|
134
|
+
Input SVG file. Can be overridden by the `-i INPUT` option with argument
|
|
135
|
+
|
|
136
|
+
- `$.bkgClass`, `$.targets.target.bkgClass`
|
|
137
|
+
|
|
138
|
+
CSS class to detect background. Default for the former: "background". The latter overrides the former.
|
|
139
|
+
|
|
140
|
+
- `$.frgClass`, `$.targets.target.frgClass`
|
|
141
|
+
|
|
142
|
+
CSS class to detect foreground. Default for the former: "foreground". The latter overrides the former.
|
|
143
|
+
|
|
144
|
+
- `$.outType`, `$.targets.target.outType`
|
|
145
|
+
|
|
146
|
+
The output file type (no leading dot): png, webp, etc. The latter overrides the former.
|
|
147
|
+
|
|
148
|
+
- `$.targets`
|
|
149
|
+
|
|
150
|
+
Array of rules for each output image file defined as follows:
|
|
151
|
+
|
|
152
|
+
- `$.targets.target.title`
|
|
153
|
+
|
|
154
|
+
Plain text to log the progress
|
|
155
|
+
|
|
156
|
+
- `$.targets.target.delete`
|
|
157
|
+
|
|
158
|
+
If `true`, delete all files listed under the target (useful if, for instance, all images have been converted to a single `.ico` file)
|
|
159
|
+
|
|
160
|
+
- `$.targets.target.outDir`
|
|
161
|
+
|
|
162
|
+
Output sub-directory (relative to the top-level `rootDir`) or an absolute path
|
|
163
|
+
|
|
164
|
+
- `$.targets.target.output`
|
|
165
|
+
|
|
166
|
+
Array of the output dimensions and filenames (under `outDir` or a path)
|
|
167
|
+
|
|
168
|
+
- `$.targets.target.output.size`
|
|
169
|
+
|
|
170
|
+
Dimensions in pixels of the background as a single number (square) or `WxH` (rectangle).It migt be followed by dimensions of the foreground. Use space(s) to separate foreground size from the background one.
|
|
171
|
+
|
|
172
|
+
- `$.targets.target.output.file`
|
|
173
|
+
|
|
174
|
+
Name of the output image file (sub-path relative to `outDir`)
|
|
175
|
+
|
|
176
|
+
### Placeholders to use in commands
|
|
177
|
+
|
|
178
|
+
Do not wrap those in quotes unless necessary, and not for being "safe" with possible spaces inside:
|
|
179
|
+
|
|
180
|
+
- `{i}`
|
|
181
|
+
|
|
182
|
+
Input (SVG) file path as passed to the utility, if not present in the full command, the content will be fed to the respective application via pipe
|
|
183
|
+
|
|
184
|
+
- `{n}`
|
|
185
|
+
|
|
186
|
+
Input filename without type (extension). When having multiple, without any: up to the first dot.
|
|
187
|
+
|
|
188
|
+
- `{o}`
|
|
189
|
+
|
|
190
|
+
Current output file path.
|
|
191
|
+
|
|
192
|
+
- `{t}`
|
|
193
|
+
|
|
194
|
+
Current output file type defined in `outType`.
|
|
195
|
+
|
|
196
|
+
- `{w}`
|
|
197
|
+
|
|
198
|
+
Current output image width: largest of two widths (background and foreground).
|
|
199
|
+
|
|
200
|
+
- `{h}`
|
|
201
|
+
|
|
202
|
+
Current output image height: largest of two heights (background and foreground).
|
|
203
|
+
|
|
204
|
+
### Extra Expansions
|
|
205
|
+
|
|
206
|
+
References to the environment variables will be expanded:
|
|
207
|
+
|
|
208
|
+
- Portable: `$ABC`, `${ABC:-$DEF}`.
|
|
209
|
+
- Windows: `%ABC%`.
|
|
210
|
+
|
|
211
|
+
References to the arguments passed to the script will be also expanded:
|
|
212
|
+
|
|
213
|
+
- Portable: `$1`, `${2:-abc}`.
|
|
214
|
+
- Windows: `%1`, `%2`.
|
|
215
|
+
|
|
216
|
+
## __Good Luck!__
|
svg2many-0.3.0/README.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# svg2many (C) Alexander Iurovetski 2025
|
|
2
|
+
|
|
3
|
+
## Convert an SVG file to raster images of multiple sizes, optionally splitting into background and foreground images
|
|
4
|
+
|
|
5
|
+
This application allows to produce all raster images you need (`.png`, `.webp`, or others) from a single `.svg` file. It is based on search-and-replace of the width, height and the presence of foreground and background in the content of the source file. The main idea is that since the `SVG` format is text (XML), there is a rational way to find spots where the default width, height, scale, offset and visibility should be substituted with required ones.
|
|
6
|
+
|
|
7
|
+
Dependencies: `envara`.
|
|
8
|
+
|
|
9
|
+
Pre-requisites (external dependencies):
|
|
10
|
+
|
|
11
|
+
1. An exporter from an `.svg` to a raster image file (`.png`, `.webp`, or others). This could be even your browser running in the headless mode, like _Chromium_-based one (Google Chrome, Microsoft Edge, Opera, Vivaldi, etc.) or _Firefox-based_ (Firefox, Tor, LibreWolf, etc.). The preferred exporter, however, is `rsvg-convert` from the GNOME's `librsvg2`. Depending on the OS you are running, it can be installed via `apt`, `yum`, `brew` or `chocolatey`. This exporter is faster than any headless browser or tools like `ImageMagick` or `Inkscape`, and produces images of good quality.
|
|
12
|
+
|
|
13
|
+
2. A converter from a set of raster images to `.ico` if you need to generate Windows native icons. Preferred converter is ImageMagick's `magick` (see the examples). You'll use that in the `after` attribute of configuration file.
|
|
14
|
+
|
|
15
|
+
3. There is no converter from a set of raster image files to a single `.icns` one, as the latter is deprecated by Apple (still supported for the sake of legacy though). That's why the examples for Flutter and macOS application icons do not utilise that. You are welcome to utilise that in your configuration files if you like. Please note however, that I had issues adding a 64x64 image to `.icns` using `png2icns` on Linux, and decided it is not worth the effort.
|
|
16
|
+
|
|
17
|
+
### Usage
|
|
18
|
+
|
|
19
|
+
This example can be used to generate all launcher icons for a _Flutter_ project. See also: _How Do I Use It_ at the end of this document
|
|
20
|
+
|
|
21
|
+
1. Install `svg2many` from _PyPI_
|
|
22
|
+
|
|
23
|
+
2. Create your beautiful SVG image. It is highly recommended NOT to use percentages as co-ordinates or sizes: those are getting scaled inconsistently, and so far, I have no solution that does not attempt a full-scale to parseing of an SVG. You can define a 100x100 pixel image that will essentially express the same. Example:
|
|
24
|
+
|
|
25
|
+
```xml
|
|
26
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
|
|
27
|
+
<g class="background" display="" transform="scale(1, 1) translate(0, 0)">
|
|
28
|
+
<!--Place your actual background drawing here-->
|
|
29
|
+
</g>
|
|
30
|
+
<g class="foreground" display="" transform="scale(1, 1) translate(0, 0)">
|
|
31
|
+
<!--Place your actual foreground drawing here-->
|
|
32
|
+
</g>
|
|
33
|
+
</svg>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
3. Create configuration file or take that from `examples/` in the application bundle or from the [repo's examples](https://github.com/aiurovet/svg2many/tree/main/examples)
|
|
37
|
+
|
|
38
|
+
4. Create `.env` file(s) or take those from `examples/` if you need. You can skip this step and make decision later.
|
|
39
|
+
|
|
40
|
+
5. Ensure the installation directory for `svg2many` is listed in `PATH` (or use an explicit path inside a wrapper script).
|
|
41
|
+
|
|
42
|
+
6. Run with options in any order:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
svg2many -c (your-config-file) [-r (top-dir)] [-i (input-svg)]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
All options:
|
|
49
|
+
|
|
50
|
+
- `-h, --help`
|
|
51
|
+
|
|
52
|
+
Help screen (similar to this list)
|
|
53
|
+
|
|
54
|
+
- `-c, --config CONFIG`
|
|
55
|
+
|
|
56
|
+
A file in JSON format that holds rules of conversion (see full description below). This setting is mandatory.
|
|
57
|
+
|
|
58
|
+
- `-d, --delete`
|
|
59
|
+
|
|
60
|
+
Delete all generated files, but not directories.
|
|
61
|
+
|
|
62
|
+
- `-e, --env ENV`
|
|
63
|
+
|
|
64
|
+
A text file containing lines in the `name = value` format with any number of spaces in between: `CMD_RSVG="rsvg-convert"`, then `CMD_RSVG_OUT_FILE="$CMD_RSVG --output {o}"`. It allows you to define extra environment variables to use in different configuration files. You can put there comments as well (starting with #). The application will load the content from `.env`, then `any.env`, then `posix.env` on POSIX-compatible OSes (Linux, BSD, macOS, AIX), then `bsd.env` (for FreeBSD, NetBSD, etc.), then `<OS>.env` (\<OS\> is what Python's `platform.system()` call returns, or also `macos.env` on macOS). On Windows, it would be `.env`, `windows.env`, Then, if this option is specified, that particular file. The order is important: from generic to more and more specific ones, having the later similar value overriding the earlier one. All these files will be scanned and taken from either the directory of the specified ENV or the config file's one otherwise. You do not have to have them all: the application will pick only those that are present without any warning or error that some are missing. This approach allows you to make portable (OS-independent) conversions if you need. For instance, generating images under GitHub actions, you have a luxury of automatic choice: $HOME on UNIX-like systems, $USERPROFILE on Windows, speciific paths to exporters on macOS like _"Applications/Google Chrome.app/Contents/MacOS/Google Chrome"_, and _google-chrome_ on Linux.
|
|
65
|
+
|
|
66
|
+
- `-i, --input INPUT`
|
|
67
|
+
|
|
68
|
+
An `.svg` file to convert. If INPUT is a mere - (dash), the SVG content will be read from `stdin`. Overrides `inpFile` in the configuration file.
|
|
69
|
+
|
|
70
|
+
- `-q, --quiet`
|
|
71
|
+
|
|
72
|
+
Do not print any information to the console. Mutually exclusive with `-v, --verbose`.
|
|
73
|
+
|
|
74
|
+
- `-r, --root ROOT`
|
|
75
|
+
|
|
76
|
+
Project top directory for all relative paths. Overrides `rootDir` in the configuration file.
|
|
77
|
+
|
|
78
|
+
- `-v, --verbose`
|
|
79
|
+
|
|
80
|
+
Detailed logging, primarily, to trace issues. Mutually exclusive with `-q` or `--quiet`.
|
|
81
|
+
|
|
82
|
+
The default SVG-to-raster exporter is `rsvg-convert` (to PNG), created and maintained by the GNOME project. This is the fastest and accurate way to create raster images. If you need to export to another raster image format, there is a good chance you can do that by directing the output to `stdout`, then reading into the next exporter via `stdin` (piping). See the `export` attribute in th sample configuration files.
|
|
83
|
+
|
|
84
|
+
ImageMagick and Inkscape are less performant, and also earlier, were producing images of lower quality. It looks like this area was improved. However, when I tried to use ImageMagick's `convert`, it failed. After I installed Inkscape, it suddenly started working. Please verify yourself if you would like to use it. My own preference, though, is `rsvg-convert`
|
|
85
|
+
|
|
86
|
+
Headless Chrome is another option: it supports more SVG features, but runs slower. More importantly, it is frequently broken (and it is now, as of December 2025, on Kubuntu 25.04), and the fix might take a while to come. To my memory, it was broken at least twice within a few years. The issues, in fact, were in Chromium, which is even worse, as it impacts a wider range of browsers.
|
|
87
|
+
|
|
88
|
+
Last but not least comes headless Firefox. As of December 2025, on Kubuntu 25.04, it seems to have an issue similar to Chromium. It is by far the slowest one, as it is not cached like the Chromium-based browsers. It will fail when another instance is open (e.g. you are viewing a website with it). Also, it will fail to export when SVG content is sent via stdin rather than a file, so you must use `{i}` in the command.
|
|
89
|
+
|
|
90
|
+
Please note that most of these exporters convert SVG to PNG only
|
|
91
|
+
|
|
92
|
+
## JSON Configuration File Format
|
|
93
|
+
|
|
94
|
+
### Nodes
|
|
95
|
+
|
|
96
|
+
- `$.after`, `$.targets.target.after`
|
|
97
|
+
|
|
98
|
+
Default command to run upon completion of all exports in a target (like `convert` for Windows icons). The latter overrides the former.
|
|
99
|
+
|
|
100
|
+
- `$.export`, `$.targets.target.export`
|
|
101
|
+
|
|
102
|
+
Command to export an input SVG image to an output raster image file. The latter overrides the former. Might be useful to generate `webp` icons for `Android` icons specifically.
|
|
103
|
+
|
|
104
|
+
- `$.rootDir`
|
|
105
|
+
|
|
106
|
+
Top directory for the input and output files. Can be overridden by the `-r ROOT` option with argument
|
|
107
|
+
|
|
108
|
+
- `$.inpFile`
|
|
109
|
+
|
|
110
|
+
Input SVG file. Can be overridden by the `-i INPUT` option with argument
|
|
111
|
+
|
|
112
|
+
- `$.bkgClass`, `$.targets.target.bkgClass`
|
|
113
|
+
|
|
114
|
+
CSS class to detect background. Default for the former: "background". The latter overrides the former.
|
|
115
|
+
|
|
116
|
+
- `$.frgClass`, `$.targets.target.frgClass`
|
|
117
|
+
|
|
118
|
+
CSS class to detect foreground. Default for the former: "foreground". The latter overrides the former.
|
|
119
|
+
|
|
120
|
+
- `$.outType`, `$.targets.target.outType`
|
|
121
|
+
|
|
122
|
+
The output file type (no leading dot): png, webp, etc. The latter overrides the former.
|
|
123
|
+
|
|
124
|
+
- `$.targets`
|
|
125
|
+
|
|
126
|
+
Array of rules for each output image file defined as follows:
|
|
127
|
+
|
|
128
|
+
- `$.targets.target.title`
|
|
129
|
+
|
|
130
|
+
Plain text to log the progress
|
|
131
|
+
|
|
132
|
+
- `$.targets.target.delete`
|
|
133
|
+
|
|
134
|
+
If `true`, delete all files listed under the target (useful if, for instance, all images have been converted to a single `.ico` file)
|
|
135
|
+
|
|
136
|
+
- `$.targets.target.outDir`
|
|
137
|
+
|
|
138
|
+
Output sub-directory (relative to the top-level `rootDir`) or an absolute path
|
|
139
|
+
|
|
140
|
+
- `$.targets.target.output`
|
|
141
|
+
|
|
142
|
+
Array of the output dimensions and filenames (under `outDir` or a path)
|
|
143
|
+
|
|
144
|
+
- `$.targets.target.output.size`
|
|
145
|
+
|
|
146
|
+
Dimensions in pixels of the background as a single number (square) or `WxH` (rectangle).It migt be followed by dimensions of the foreground. Use space(s) to separate foreground size from the background one.
|
|
147
|
+
|
|
148
|
+
- `$.targets.target.output.file`
|
|
149
|
+
|
|
150
|
+
Name of the output image file (sub-path relative to `outDir`)
|
|
151
|
+
|
|
152
|
+
### Placeholders to use in commands
|
|
153
|
+
|
|
154
|
+
Do not wrap those in quotes unless necessary, and not for being "safe" with possible spaces inside:
|
|
155
|
+
|
|
156
|
+
- `{i}`
|
|
157
|
+
|
|
158
|
+
Input (SVG) file path as passed to the utility, if not present in the full command, the content will be fed to the respective application via pipe
|
|
159
|
+
|
|
160
|
+
- `{n}`
|
|
161
|
+
|
|
162
|
+
Input filename without type (extension). When having multiple, without any: up to the first dot.
|
|
163
|
+
|
|
164
|
+
- `{o}`
|
|
165
|
+
|
|
166
|
+
Current output file path.
|
|
167
|
+
|
|
168
|
+
- `{t}`
|
|
169
|
+
|
|
170
|
+
Current output file type defined in `outType`.
|
|
171
|
+
|
|
172
|
+
- `{w}`
|
|
173
|
+
|
|
174
|
+
Current output image width: largest of two widths (background and foreground).
|
|
175
|
+
|
|
176
|
+
- `{h}`
|
|
177
|
+
|
|
178
|
+
Current output image height: largest of two heights (background and foreground).
|
|
179
|
+
|
|
180
|
+
### Extra Expansions
|
|
181
|
+
|
|
182
|
+
References to the environment variables will be expanded:
|
|
183
|
+
|
|
184
|
+
- Portable: `$ABC`, `${ABC:-$DEF}`.
|
|
185
|
+
- Windows: `%ABC%`.
|
|
186
|
+
|
|
187
|
+
References to the arguments passed to the script will be also expanded:
|
|
188
|
+
|
|
189
|
+
- Portable: `$1`, `${2:-abc}`.
|
|
190
|
+
- Windows: `%1`, `%2`.
|
|
191
|
+
|
|
192
|
+
## __Good Luck!__
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Common-base env file for portablility
|
|
3
|
+
#
|
|
4
|
+
# Defines common environment variables like HOME for the user home directory
|
|
5
|
+
# Uses POSIX rules for the environment variables and CLI arguments expansion
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
HOME=${HOME:-${USERPROFILE:-${SYS\$LOGIN:-${UnixEnv\$HOME}}}}
|
|
9
|
+
|
|
10
|
+
ARG_HEADLESS="--headless --disable-gpu --default-background-color=00000000 --window-size={w},{h} --screenshot={o} file://{i}"
|
|
11
|
+
CMD_MAGICK="magick {i} {o}"
|
|
12
|
+
CMD_RSVG="rsvg-convert"
|
|
13
|
+
CMD_RSVG_TO_FILE="$CMD_RSVG --output {o}"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"help": [
|
|
3
|
+
"See app-icons-flutter.json"
|
|
4
|
+
],
|
|
5
|
+
"envType": "POSIX",
|
|
6
|
+
"export": "$CMD_RSVG_TO_FILE",
|
|
7
|
+
"rootDir": "examples",
|
|
8
|
+
"inpFile": "assets/images/app_icon.svg",
|
|
9
|
+
"outType": "png",
|
|
10
|
+
"frgClass": null,
|
|
11
|
+
"bkgClass": null,
|
|
12
|
+
"targets": [{
|
|
13
|
+
"export": "$CMD_RSVG | cwebp -q 80 -o {o} -quiet -- -",
|
|
14
|
+
"outType": "webp",
|
|
15
|
+
"title": "Android app icons",
|
|
16
|
+
"outDir": "android/app/src/main/res",
|
|
17
|
+
"output": [
|
|
18
|
+
{"size": " 0 48", "file": "drawable-mdpi/ic_launcher_foreground.{t}"},
|
|
19
|
+
{"size": " 48x48 0", "file": "drawable-mdpi/ic_launcher_background.{t}"},
|
|
20
|
+
{"size": " 0 72", "file": "drawable-hdpi/ic_launcher_foreground.{t}"},
|
|
21
|
+
{"size": " 72 0x0", "file": "drawable-hdpi/ic_launcher_background.{t}"},
|
|
22
|
+
{"size": " 0x0 96", "file": "drawable-xhdpi/ic_launcher_foreground.{t}"},
|
|
23
|
+
{"size": " 96 0", "file": "drawable-xhdpi/ic_launcher_background.{t}"},
|
|
24
|
+
{"size": " 0 144", "file": "drawable-xxhdpi/ic_launcher_foreground.{t}"},
|
|
25
|
+
{"size": " 144 0", "file": "drawable-xxhdpi/ic_launcher_background.{t}"},
|
|
26
|
+
{"size": " 0 192x192", "file": "drawable-xxxhdpi/ic_launcher_foreground.{t}"},
|
|
27
|
+
{"size": " 192 0", "file": "drawable-xxxhdpi/ic_launcher_background.{t}"},
|
|
28
|
+
|
|
29
|
+
{"size": " 48", "file": "mipmap-mdpi/ic_launcher.{t}"},
|
|
30
|
+
{"size": " 72", "file": "mipmap-hdpi/ic_launcher.{t}"},
|
|
31
|
+
{"size": "96x96", "file": "mipmap-xhdpi/ic_launcher.{t}"},
|
|
32
|
+
{"size": " 144", "file": "mipmap-xxhdpi/ic_launcher.{t}"},
|
|
33
|
+
{"size": " 192", "file": "mipmap-xxxhdpi/ic_launcher.{t}"}
|
|
34
|
+
]
|
|
35
|
+
}]
|
|
36
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
{
|
|
2
|
+
"help": [
|
|
3
|
+
"",
|
|
4
|
+
"Nodes",
|
|
5
|
+
"",
|
|
6
|
+
"export - default command to export an input SVG image to an output raster image file",
|
|
7
|
+
"after - default command to run upon completion of all exports in a target (like conversion to .ico)",
|
|
8
|
+
"rootDir - top directory for the input and output files (absolute or relative to the current one)",
|
|
9
|
+
"inpFile - input SVG file (optional, might be passed explicitly as an arg)",
|
|
10
|
+
"bkgClass - class to detect background (default: \"background\")",
|
|
11
|
+
"frgClass - class to detect foreground (default: \"foreground\")",
|
|
12
|
+
"outType - default output file type (no leading dot): png, webp, etc.",
|
|
13
|
+
"targets - array of rules for each output image file defined as follows:",
|
|
14
|
+
" export - command to export an input SVG image to an output raster image file",
|
|
15
|
+
" after - command to run upon completion of all exports in a target (like conversion to .ico)",
|
|
16
|
+
" title - title of the current target (plain text to display)",
|
|
17
|
+
" outDir - output sub-directory of rootDir or an absolute path",
|
|
18
|
+
" outType - the output file type (no leading dot): png, webp, etc.",
|
|
19
|
+
" output - array of the output dimensions and filenames (under outDir or a path)",
|
|
20
|
+
" delete - if 'true', delete all files listed under this target (useful if, for",
|
|
21
|
+
" instance, all images have been converted to a single .ico file)",
|
|
22
|
+
" size - dimensions in pixels of the background as a single number (square) or",
|
|
23
|
+
" WxH (rectangle); optionally followed by dimensions of the foreground;",
|
|
24
|
+
" use space(s) to separate foreground size from the background one",
|
|
25
|
+
" file - name of the output image file, may contain a (sub-)directory",
|
|
26
|
+
"",
|
|
27
|
+
"Placeholders",
|
|
28
|
+
"",
|
|
29
|
+
"(do not wrap those in quotes unless necessary, and not for being \"safe\" with possible spaces inside)",
|
|
30
|
+
"",
|
|
31
|
+
"{i} - input (SVG) file path as passed to the utility, if not present in the full",
|
|
32
|
+
" command, the SVG content will be fed to the respective application via pipe",
|
|
33
|
+
"{n} - input filename without type (extension), when having multiple, without any",
|
|
34
|
+
"{o} - current output file path",
|
|
35
|
+
"{t} - current output file type defined in outType",
|
|
36
|
+
"{w} - current output image width: largest of two widths",
|
|
37
|
+
"{h} - current output image height: largest of two heights",
|
|
38
|
+
"",
|
|
39
|
+
"Environment variables can be used in the UNIX format",
|
|
40
|
+
"Arguments passed to the script will be also expanded: use numbers in curly brackets",
|
|
41
|
+
""
|
|
42
|
+
],
|
|
43
|
+
"envType": "POSIX",
|
|
44
|
+
"export": "$CMD_RSVG_TO_FILE",
|
|
45
|
+
"rootDir": "~/Projects/$1/examples",
|
|
46
|
+
"inpFile": "assets/images/app_icon.svg",
|
|
47
|
+
"outType": "png",
|
|
48
|
+
"frgClass": null,
|
|
49
|
+
"bkgClass": null,
|
|
50
|
+
"targets": [{
|
|
51
|
+
"export": "$CMD_RSVG | cwebp -q 80 -o {o} -quiet -- -",
|
|
52
|
+
"outType": "webp",
|
|
53
|
+
"title": "Android app icons",
|
|
54
|
+
"outDir": "android/app/src/main/res",
|
|
55
|
+
"output": [
|
|
56
|
+
{"size": " 0 48", "file": "drawable-mdpi/ic_launcher_foreground.{t}"},
|
|
57
|
+
{"size": " 48x48 0", "file": "drawable-mdpi/ic_launcher_background.{t}"},
|
|
58
|
+
{"size": " 0 72", "file": "drawable-hdpi/ic_launcher_foreground.{t}"},
|
|
59
|
+
{"size": " 72 0x0", "file": "drawable-hdpi/ic_launcher_background.{t}"},
|
|
60
|
+
{"size": " 0x0 96", "file": "drawable-xhdpi/ic_launcher_foreground.{t}"},
|
|
61
|
+
{"size": " 96 0", "file": "drawable-xhdpi/ic_launcher_background.{t}"},
|
|
62
|
+
{"size": " 0 144", "file": "drawable-xxhdpi/ic_launcher_foreground.{t}"},
|
|
63
|
+
{"size": " 144 0", "file": "drawable-xxhdpi/ic_launcher_background.{t}"},
|
|
64
|
+
{"size": " 0 192x192", "file": "drawable-xxxhdpi/ic_launcher_foreground.{t}"},
|
|
65
|
+
{"size": " 192 0", "file": "drawable-xxxhdpi/ic_launcher_background.{t}"},
|
|
66
|
+
|
|
67
|
+
{"size": " 48", "file": "mipmap-mdpi/ic_launcher.{t}"},
|
|
68
|
+
{"size": " 72", "file": "mipmap-hdpi/ic_launcher.{t}"},
|
|
69
|
+
{"size": "96x96", "file": "mipmap-xhdpi/ic_launcher.{t}"},
|
|
70
|
+
{"size": " 144", "file": "mipmap-xxhdpi/ic_launcher.{t}"},
|
|
71
|
+
{"size": " 192", "file": "mipmap-xxxhdpi/ic_launcher.{t}"}
|
|
72
|
+
]
|
|
73
|
+
}, {
|
|
74
|
+
"title": "iOS/iPadOS app icons",
|
|
75
|
+
"outDir": "ios/Runner/Assets.xcassets/AppIcon.appiconset",
|
|
76
|
+
"output": [
|
|
77
|
+
{"size": " 20", "file": "Icon-20x20@1x.{t}"},
|
|
78
|
+
{"size": " 40", "file": "Icon-20x20@2x.{t}"},
|
|
79
|
+
{"size": " 60", "file": "Icon-20x20@3x.{t}"},
|
|
80
|
+
{"size": "29x29", "file": "Icon-20x20@1x.{t}"},
|
|
81
|
+
{"size": " 58", "file": "Icon-29x29@2x.{t}"},
|
|
82
|
+
{"size": " 87", "file": "Icon-29x29@3x.{t}"},
|
|
83
|
+
{"size": " 80", "file": "Icon-40x40@2x.{t}"},
|
|
84
|
+
{"size": " 120", "file": "Icon-60x60@2x.{t}"},
|
|
85
|
+
{"size": " 180", "file": "Icon-60x60@3x.{t}"},
|
|
86
|
+
{"size": " 76", "file": "Icon-76x76@1x.{t}"},
|
|
87
|
+
{"size": " 152", "file": "Icon-76x76@2x.{t}"},
|
|
88
|
+
{"size": " 167", "file": "Icon-83.5x83.5@2x.{t}"},
|
|
89
|
+
{"size": " 1024", "file": "Icon-1024x1024@1x.{t}"}
|
|
90
|
+
]
|
|
91
|
+
}, {
|
|
92
|
+
"title": "Linux app icon",
|
|
93
|
+
"outDir": "assets/images",
|
|
94
|
+
"output": [
|
|
95
|
+
{"size": "192", "file": "{n}.{t}"}
|
|
96
|
+
]
|
|
97
|
+
}, {
|
|
98
|
+
"title": "macOS app icons",
|
|
99
|
+
"outDir": "macos/Runner/Assets.xcassets/AppIcon.appiconset",
|
|
100
|
+
"output": [
|
|
101
|
+
{"size": " 16", "file": "Icon-{w}x{h}.{t}"},
|
|
102
|
+
{"size": " 32", "file": "Icon-{w}x{h}.{t}"},
|
|
103
|
+
{"size": " 64", "file": "Icon-{w}x{h}.{t}"},
|
|
104
|
+
{"size": " 128", "file": "Icon-{w}x{h}.{t}"},
|
|
105
|
+
{"size": " 256", "file": "Icon-{w}x{h}.{t}"},
|
|
106
|
+
{"size": " 512", "file": "Icon-{w}x{h}.{t}"},
|
|
107
|
+
{"size": "1024", "file": "Icon-{w}x{h}.{t}"}
|
|
108
|
+
]
|
|
109
|
+
}, {
|
|
110
|
+
"title": "Website icons",
|
|
111
|
+
"outDir": "web/icons",
|
|
112
|
+
"output": [
|
|
113
|
+
{"size": "16", "file": "../favicon.{t}"},
|
|
114
|
+
|
|
115
|
+
{"size": " 16x16", "file": "favicon-{w}x{h}.{t}"},
|
|
116
|
+
{"size": " 32", "file": "favicon-{w}x{h}.{t}"},
|
|
117
|
+
{"size": "192x192", "file": "{n}-{w}.{t}"},
|
|
118
|
+
{"size": " 512", "file": "{n}-{w}.{t}"},
|
|
119
|
+
|
|
120
|
+
{"size": " 192 154x154", "file": "{n}-maskable-{w}.{t}"},
|
|
121
|
+
{"size": "512x512 410", "file": "{n}-maskable-{w}.{t}"}
|
|
122
|
+
]
|
|
123
|
+
}, {
|
|
124
|
+
"title": "Windows app icon",
|
|
125
|
+
"outDir": "windows/runner/resources",
|
|
126
|
+
"after": "magick {n}-16x16.{t} {n}-24x24.{t} {n}-32x32.{t} {n}-48x48.{t} {n}-64x64.{t} {n}-256x256.{t} {n}.ico",
|
|
127
|
+
"delete": "true",
|
|
128
|
+
"output": [
|
|
129
|
+
{"size": " 16", "file": "{n}-{w}x{h}.{t}"},
|
|
130
|
+
{"size": " 24", "file": "{n}-{w}x{h}.{t}"},
|
|
131
|
+
{"size": " 32", "file": "{n}-{w}x{h}.{t}"},
|
|
132
|
+
{"size": " 48", "file": "{n}-{w}x{h}.{t}"},
|
|
133
|
+
{"size": " 64", "file": "{n}-{w}x{h}.{t}"},
|
|
134
|
+
{"size": "256", "file": "{n}-{w}x{h}.{t}"}
|
|
135
|
+
]
|
|
136
|
+
}]
|
|
137
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"help": [
|
|
3
|
+
"See app-icons-flutter.json"
|
|
4
|
+
],
|
|
5
|
+
"envType": "POSIX",
|
|
6
|
+
"export": "$CMD_RSVG_TO_FILE",
|
|
7
|
+
"rootDir": "examples",
|
|
8
|
+
"inpFile": "assets/images/app_icon.svg",
|
|
9
|
+
"outType": "png",
|
|
10
|
+
"frgClass": null,
|
|
11
|
+
"bkgClass": null,
|
|
12
|
+
"targets": [{
|
|
13
|
+
"title": "iOS/iPadOS app icons",
|
|
14
|
+
"outDir": "ios/Runner/Assets.xcassets/AppIcon.appiconset",
|
|
15
|
+
"output": [
|
|
16
|
+
{"size": " 20", "file": "Icon-20x20@1x.{t}"},
|
|
17
|
+
{"size": " 40", "file": "Icon-20x20@2x.{t}"},
|
|
18
|
+
{"size": " 60", "file": "Icon-20x20@3x.{t}"},
|
|
19
|
+
{"size": "29x29", "file": "Icon-20x20@1x.{t}"},
|
|
20
|
+
{"size": " 58", "file": "Icon-29x29@2x.{t}"},
|
|
21
|
+
{"size": " 87", "file": "Icon-29x29@3x.{t}"},
|
|
22
|
+
{"size": " 80", "file": "Icon-40x40@2x.{t}"},
|
|
23
|
+
{"size": " 120", "file": "Icon-60x60@2x.{t}"},
|
|
24
|
+
{"size": " 180", "file": "Icon-60x60@3x.{t}"},
|
|
25
|
+
{"size": " 76", "file": "Icon-76x76@1x.{t}"},
|
|
26
|
+
{"size": " 152", "file": "Icon-76x76@2x.{t}"},
|
|
27
|
+
{"size": " 167", "file": "Icon-83.5x83.5@2x.{t}"},
|
|
28
|
+
{"size": " 1024", "file": "Icon-1024x1024@1x.{t}"}
|
|
29
|
+
]
|
|
30
|
+
}]
|
|
31
|
+
}
|