This node module outputs a set of SQUARE favicons, webicons, pwa-icons and electron-icons as well as iOS, Windows Store and MacOS icons from an original 1240x1240 square icon that retains transparency and also minifies the assets. It will also create splash screens and two different types of svgs.
It works cross-platform to even generate those pesky .icns
and .ico
files for some reason still used by Electron apps and in the case of the latter prefered by some browsers and webscrapers (favicon.ico) - even though modern development guidelines for Apple and Windows recommend using .png
.
It has two primary interfaces (with Quasar CTX and as a standalone CLI) and although it is built for the Quasar Framework, it should work anywhere you can run node. You can even import it and use it in your own pipelines if that's your thing. It is designed to be a very useful tool that you will be glad to have lying around.
If you use an original that is smaller than 1240x1240 some icons will be naively upscaled. If you do not use a square original, it will be cropped square from the center using the smaller dimension as width and height. You have been warned.
- node / yarn
- Linux, MacOS or Windows
- A square image in png format that is at least 1240px x 1240px (much bigger will merely slow down the conversions)
- @quasar/cli version 1.0.0-beta.4 (if building a new project) or @quasar/app v1.0.0-beta.18 or later in order to add this module as an app-extension.
$ quasar ext add @quasar/icon-factory
During the install phase, the extension will ask you for a path relative to the app folder where it can find your icon source file:
? Please type a relative path to the file you want to use as your source image.
Best results with a 1240x1240 png (using transparency): (./logo-source.png)
Note: Please use a valid png of 1240x1240 pixels. If you choose an image that is not square or has smaller dimensions, the icon-factory will do its best, but the results will not be optimal. Transparency is recommended. PNG is required.
Then choose a minification strategy:
? Minify strategy to be used during development: (Use arrow keys)
❯ pngquant (rate: 0.225 | quality: lossy | time: 01.4s)
pngout (rate: 0.94 | quality: lossless | time: 10.7s)
optipng (rate: 0.61 | quality: lossless | time: 13.9s)
pngcrush (rate: 0.61 | quality: lossless | time: 28.1s)
zopfli (rate: 0.57 | quality: lossless | time: 33.2s)
Note: we recommend using pngquant because it is the fastest. The times given are approximations for SPA. Other targets will take more time.
You will be asked the same questions for production. Our recommendation is to choose optipng
. It has the best time / quality trade-off for a lossless minification.
Your selections will be registered and filehashes registered to the new file quasar.icon-factory.json
in the root folder of your project repository. If you do not change this file - or you do not replace the source image - icon-factory will do nothing.
The first time you start Quasar, icon-factory will create the images needed for the specific app artifacts. They will not automatically be added to git, so you will need to manage that yourself.
$ quasar dev --mode electron
If you change the image, the settings in quasar.icon-factory.json
or the dev/build mode, this extension will be triggered and build your assets in the appropriate place. Don't forget to check the results and commit them.
If you choose to build icons for Cordova, on iOS they WILL have a colored background (because transparency is not allowed), and this is why you are asked for an RGB value during the install phase. (Android allows transparency, btw.) You can change this in the quasar.icon-factory.json, but be sure to use a valid hex code like: #c0ff33
.
This colored background color will also be used for the splashscreen. If you don't provide one, black will be used. If you haven't already installed the cordova-plugin-splashscreen, it will be installed for you.
There are 5 1/2 things that icon-factory does with your original file. It will create a set of webicons for your project, it will minify those icons, it can make special icns (Mac) / ico (Windows) files for apps that need them and it will create SVG assets. Finally it will sort these icons into folders.
Here is the description of these general functions that are used internally to compose icon sets and if you just want to use them, feel free:
- build - This function creates all assets requested from the sizes object or presets object.
- minify - The default usage minifies all assets in the target folder in-place with
pngquant
. Compared to usingpngcrush --brute
, it is a relatively fast process. If you are not in a hurry and want the best results, consider using pngcrush instead. - icns - This will create the special MacOS (icns) and Windows icon (ico) files.
- favicon - This will create the classical and never going out of style favicon.ico
- svg - With this command you can trace the outlines of your PNG to create an SVG and style it with some options.
- svgduochrome - This tool will help you make a posterized SVG from your PNG. Choose your colors and setting wisely.
There are five composed "recipes" that will create icons for you according to your needs as assembled by our research:
- cordova (all icons, splashscreens, all platforms)
- electron (all platforms)
- pwa (incl. chrome special icon name, favicon)
- spa (common icon sizes, favicon)
- kitchensink (all icons, all platforms)
You may notice that very small icons (like 16x16 and 32x32) look a little strange. Achieving good results by simply downscaling to a very small size depends a great deal on your original, and it is highly recommended that you at least look at all of the icons before you publish your project to a store. While integration testing can make sure that you have an asset, judging the ability of your small icon to express the same content as a large one is highly subjective and something better left to humans. Not even hamming distance will get this right!
There are literally dozens of other projects out there that more or less do the same thing, why did you bother to make a new one? The answer is quite simple: Because none of them fulfill all the needs of the quasar project, and although lots of really smart people built them, we want to be able to maintain this library and grow it as quasar grows. Especially since many such image-library projects quickly grow outdated and maintainers drift away into a sea of micro-modules, we felt that it is a good property to keep "in-house".
Furthermore, we wanted to pay special attention to your security and it was obvious that other libraries aren't doing enough to protect developers.
There are six different minification algorithms available (because it is possible that one or the other just won't build on your system or worse becomes compromised via some kind of exploit). Using totally non-scientific tests, these are the results of this command that ran one time on a 3,2 GHz Quad-Core Intel Xeon with 16 GB of ram:
$ time node cli.js -p=spa -s=test/example-1240x1240.png -t=test/output -m="$minify" && du -sh test/output/spa
It takes a source image, scales it down according to the settings and then minifies it according to the library listed and the default settings tuned to give the best results.
Library | Time | Quality | Size |
---|---|---|---|
no minify | 00.7s | original | 664K |
pngquant-bad | 00.9s | very lossy | 100K |
pngquant-good | 01.4s | lossy | 144K |
pngout | 10.7s | lossless | 624K |
optipng | 13.9s | lossless | 404K |
pngcrush | 28.1s | lossless | 404K |
zopfli | 33.2s | lossless | 380K |
zopfli.more | 81.3s | lossless | 336K |
This is why it is recommended to use pngquant during development (to have a proxy image), but to use optipng when building for production.
These are notoriously difficult to acquire and make. For icns you usually need a mac and ico is really just a sequence of images with a special header - but there are very few tools that will let you do both cross-platform - and this is one case where we needed several tools.
This module uses the amazing png2icons
module, which actually does all of the decoding and encoding on a byte-level with javascript. This of course takes a bit of time, but it also works cross-platform, so please think about going over there and giving those devs a ⭐. This is actually one of the slowest parts of the kitchensink
and the files are huge. By feeding it from the sharp
buffer it has been sped up a little bit (and the final icns file is actually about 20% smaller!)
To make the favicon.ico, it uses to-ico
and concats a 16x16 and a 32x32 png.
These are constructed for your app and use your project's background color for the background. If you undefine this value, the process will automatically create a black background. You can also change the option with a hex triplet like #c0ffee
.
The safari-pinned-tab.svg
mask is created by adding contrast (via threshold) to the original and then applying even more threshold to the SVG tracing. If you set a background color, the mask will be solid, which is probably not what you want. If you are indeed of a discerning nature (and have used gradients in your icon design), there is another option available to you:svg-duochrome. It too will be created in the spa folder within the spa task. As usual, you can also override our sensible defaults and get some wild SVG action going on.
Here are the options you will want to set:
options: {
background_color: '#000074',
theme_color: '#02aa9b',
svg: {
png_threshold: 200,
svg_threshold: 128,
turdSize: 3,
optTolerance: 0.3,
steps: [40, 85, 135, 180]
},
}
quasar-icon-factory
can be used as a command line tool for batch invocation, and you can simply add it by installing it "globally" with your node package manager:
$ yarn global add quasar-icon-factory
- or -
$ npm install --global quasar-icon-factory
To find out about the settings, just use
$ iconfactory --help
Quasar Icon Factory: v.1.0.0
License: MIT
Icon Factory is a node utility to create a batch of icons for your app.
Designed to work seamlessly with the Quasar Framework, but probably
useful for other build pipelines.
Flags:
-p, --preset Choose a preset output or make your own
[minify|splash|svg|svgduochrome|favicon]
[spa|pwa|cordova|electron|kitchensink|custom]
-s, --source Your source image as a large square png
-t, --target The destination directory for the files created
-o, --options path to file that overrides defaults (if custom)
-m, --minify Minify strategy to use.
[pngcrush|pngquant|optipng|pngout|zopfli]
-d, --mode Minify mode if minify preset [folder|singlefile]
-v, --version display version information
-h, --help display this information
Usage:
$ iconfactory -p=kitchensink -s=icon-1280x1280.png -t=./outputFolder -m=pngquant
$ iconfactory -p=minify -s=icon-1240x1240.png -t=./output -m=pngquant -d=singlefile
Solving compression problems takes time, and the more complex the approach the more linear time is needed. Some compression algorithms are fast, some are great. None are both. This package tries to write from the buffer only when a file is created and (mostly) avoids creating intermediary files.
git clone
, yarn install
, yarn test
We only permit you to use .png files as the source, and there is a magic-number
check to ensure that the file being processed is indeed a valid and proper image/png
. Furthermore, there are neither imagemagick nor graphicsmagick dependencies and this project should build and run on all platforms supported by @quasar/cli.
You are totally welcome to join this project. Please file issues and make PRs! Let us know how it goes and join us at our discord server to talk shop. There are a number of tasks that will be marked as "help wanted" on the Issue board, so please make sure to have a look there.
- Favicon Cheat Sheet
- PWA Icons
- PWA for Chrome
- PWA on iOS
- Lighthouse Web App Audit
- MacOS App Icon
- iOS App Icons
- iOS Ad Hoc Mode
- Cordova Icons
- Electron Icons
- Windows Icon Assets
- Windows APPX Icons
- Windows MRT Cordova Image Spec
- favicon.ico vs favicon.png
- Material Icons
- Favicon Checker
- Wikipedia PNG Optimizing
- PNG Minification Comparison
- .ico file-header Information
Stage 0 - Collection
- CLI interface
- Switch for Cordova / Electron / Webapps
- Get all the sizes!!!
- Find cross-platform alternative for MacOS .icns
- Find a smaller (and safe!) alternative to graphicsmagick
- Be smarter about chaining
- pngquant the results
- get some svg's in there yo
Stage 1 - Connection
- Node API interface
- Webpack plugin extension
- - rebuild the options and config
- - map to quasar outputs
- Add debug logging (verbose, minimal, file, none)
Stage 2 - Refactoring
- Complete set of unit tests with 95% coverage target
- Audit imagemin lib and deps
- Build JSDocs on git precommit
- Real benchmarks
- Refactor internal methods and patterns to streamline process
- - multithreading of sharp via .clone()
- - be even smarter about only REALLY making the icons that are needed and then writing targets from that specific buffer
- image-trace-loader
- the image-min team
- @TobyMosque, @maxMatteo, @Robin, @Rob, @trendchaser4u, @bloo_df
- Code: MIT
- © 2018: Present Daniel Thompson-Yvetot & Razvan Stoenescu
- Original Image for iconfactory: Public Domain
- Modifications: Daniel Thompson-Yvetot. CC-BY