Skip to content

Make all the icons for your app. A quasar-1.0+ app-extension and stand-alone CLI.

License

Notifications You must be signed in to change notification settings

informatious/app-extension-icon-factory

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

99 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@quasar/icon-factory

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.

Installation and Usage

Requires

  • 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.

Install

$ 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.

Triggering

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.

Special notes about Cordova (iOS and Android only)

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.

How it Works

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 using pngcrush --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)

Head's Up!

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!

But why did you make this?

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.

Minify

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.

.icns & .ico

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.

Splash Screens for Cordova

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.

SVG

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]
  },
}

CLI Usage

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  

Performance

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.

Testing

git clone, yarn install, yarn test

Security

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.

Contributing

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.

Resources for more information about App Icons

Other nice resources

Future Work

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

Thanks to

Licenses

  • Code: MIT
  • © 2018: Present Daniel Thompson-Yvetot & Razvan Stoenescu
  • Original Image for iconfactory: Public Domain
  • Modifications: Daniel Thompson-Yvetot. CC-BY

About

Make all the icons for your app. A quasar-1.0+ app-extension and stand-alone CLI.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Languages

  • JavaScript 90.9%
  • Vue 6.5%
  • HTML 1.4%
  • CSS 1.2%