diff --git a/CHANGELOG.md b/CHANGELOG.md index a7d81dd1..6a6cadd9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Changed +- Replace ImageMagick / GraphicsMagick with Node.js native `Jimp` and `to-ico` - Changed hover selection from 'mouse' to 'not-touch' - Changed jpeg optimization from jpegtran to MozJPEG - Update to Foundation 6.6.1 diff --git a/documentation/requirements/macos.md b/documentation/requirements/macos.md index 13d3d01d..c9ca8444 100644 --- a/documentation/requirements/macos.md +++ b/documentation/requirements/macos.md @@ -17,8 +17,8 @@ Homebrew is the entry point to install many tools ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" ``` -#### Image processors ( [GraphicsMagick](http://www.graphicsmagick.org) / [ImageMagick](https://www.imagemagick.org) ) -These are used to manipulate images for the iconography +#### Image processors ( [GraphicsMagick](http://www.graphicsmagick.org) / [ImageMagick](https://www.imagemagick.org) ) _[deprecated]_ +These were used to manipulate images for the iconography by nwayo prior to 3.8.0 ```shell brew install graphicsmagick diff --git a/documentation/requirements/readme.md b/documentation/requirements/readme.md index df218d53..6c032f45 100644 --- a/documentation/requirements/readme.md +++ b/documentation/requirements/readme.md @@ -1,6 +1,5 @@ # Requirements - [Node.js](https://nodejs.org) ([nwayo CLI](https://www.npmjs.com/package/@absolunet/nwayo-cli)) -- [GraphicsMagick](http://www.graphicsmagick.org) / [ImageMagick](https://www.imagemagick.org) ## Installation guides - [macOS](macos.md) diff --git a/documentation/requirements/windows.md b/documentation/requirements/windows.md index f19120ec..0d5e7ff8 100644 --- a/documentation/requirements/windows.md +++ b/documentation/requirements/windows.md @@ -8,8 +8,8 @@ Chocolatey is the entry point to install many tools @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin" ``` -#### Image processors ( [GraphicsMagick](http://www.graphicsmagick.org) / [ImageMagick](https://www.imagemagick.org) ) -These are used to manipulate images for the iconography +#### Image processors ( [GraphicsMagick](http://www.graphicsmagick.org) / [ImageMagick](https://www.imagemagick.org) ) _[deprecated]_ +These were used to manipulate images for the iconography by nwayo prior to 3.8.0 ```shell choco install graphicsmagick --confirm diff --git a/packages/workflow/helpers/paths.js b/packages/workflow/helpers/paths.js index e3767b37..9c200983 100644 --- a/packages/workflow/helpers/paths.js +++ b/packages/workflow/helpers/paths.js @@ -34,6 +34,7 @@ const extension = {}; extension.bundles = 'yaml'; extension.fonts = '{woff,woff2}'; extension.images = '{gif,jpg,png,svg}'; +extension.images2x = '{jpg,png}'; extension.scripts = 'js'; extension.styles = 'scss'; extension.stylesBuild = 'css'; @@ -118,7 +119,7 @@ files.iconsIcon = `${directory.icons}/${filename.iconsIcon}`; files.iconsLarge = `${directory.icons}/${filename.iconsLarge}`; files.iconsTile = `${directory.icons}/${filename.iconsTile}`; files.images = `${directory.images}/${pattern.anytree}/*.${extension.images}`; -files.images2x = `${directory.images}/${pattern.anytree}/*@2x.${extension.images}`; +files.images2x = `${directory.images}/${pattern.anytree}/*@2x.${extension.images2x}`; files.inline = `${directory.inline}/${pattern.anytree}/*.${extension.images}`; files.raw = `${directory.raw}/${pattern.anytree}/*`; files.scripts = `${directory.scripts}/${pattern.anytree}/*.${extension.scripts}`; diff --git a/packages/workflow/helpers/toolbox.js b/packages/workflow/helpers/toolbox.js index 99ab4d20..f64675fe 100644 --- a/packages/workflow/helpers/toolbox.js +++ b/packages/workflow/helpers/toolbox.js @@ -7,11 +7,16 @@ const chalk = require('chalk'); const deepKeys = require('deep-keys'); const log = require('fancy-log'); const plumber = require('gulp-plumber'); +const gutil = require('gulp-util'); +const Jimp = require('jimp'); const without = require('lodash.without'); const merge = require('merge-stream'); const emoji = require('node-emoji'); +const path = require('path'); const prettyBytes = require('pretty-bytes'); const stream = require('stream'); +const through2 = require('through2'); +const toIco = require('to-ico'); const Vinyl = require('vinyl'); const fss = require('@absolunet/fss'); const { terminal } = require('@absolunet/terminal'); @@ -62,17 +67,64 @@ class Toolbox { } - //-- GraphicsMagick optimization - gmOptimization(gmfile, info) { - if (info.format === 'JPG') { - gmfile.noProfile().quality(95); - } + //-- Jimp wrapper + jimp(custom) { + return through2.obj(function(file, encoding, callback) { - if (info.format === 'PNG' && info.depth === 8) { - gmfile.dither(false).colors(256); - } + Jimp.read(file.contents).then((original) => { + const image = original.clone(); - return gmfile; + // Type shenanigans + let mimeType; + + switch (path.extname(file.path).slice(1).toLowerCase()) { + + case 'jpg': + mimeType = Jimp.MIME_JPEG; + image.quality(100); + break; + + case 'png': + mimeType = Jimp.MIME_PNG; + image.rgba(true); + break; + + default: break; + + } + + custom(Jimp, image); + + image.getBuffer(mimeType, (error, buffer) => { + this.push(new gutil.File({ + base: file.base, + path: file.path, + contents: buffer + })); + + return callback(error); + }); + }); + + }); + } + + + //-- Ico generator + ico(sizes) { + return through2.obj(function(file, encoding, callback) { + + toIco(file.contents, { resize: true, sizes }).then((buffer) => { + this.push(new gutil.File({ + base: file.base, + path: file.path.replace(/\.png$/u, '.ico'), + contents: buffer + })); + + return callback(); + }); + + }); } diff --git a/packages/workflow/package.json b/packages/workflow/package.json index 0ec633ef..31c716f6 100644 --- a/packages/workflow/package.json +++ b/packages/workflow/package.json @@ -55,7 +55,6 @@ "gulp-cached": "1.1.1", "gulp-debug": "4.0.0", "gulp-eslint": "6.0.0", - "gulp-gm": "0.0.9", "gulp-if": "3.0.0", "gulp-imagemin": "7.1.0", "gulp-insert": "0.5.0", @@ -69,6 +68,8 @@ "gulp-sourcemaps": "2.6.5", "gulp-stylelint": "10.0.0", "gulp-uglify": "3.0.2", + "gulp-util": "3.0.8", + "jimp": "0.9.3", "latest-version": "5.1.0", "lodash-cli": "4.17.5", "lodash.capitalize": "4.2.1", @@ -94,6 +95,8 @@ "sass": "1.25.0", "semver": "7.1.2", "slash": "3.0.0", + "through2": "3.0.1", + "to-ico": "1.1.5", "uglify-js": "3.7.7", "vinyl": "2.2.0", "yaml-lint": "1.2.4" diff --git a/packages/workflow/tasks/assets.js b/packages/workflow/tasks/assets.js index bae83c32..4106eb53 100644 --- a/packages/workflow/tasks/assets.js +++ b/packages/workflow/tasks/assets.js @@ -4,15 +4,13 @@ 'use strict'; // const debug = require('gulp-debug'); -const gulp = require('gulp'); -const gm = require('gulp-gm'); -const imagemin = require('gulp-imagemin'); -const rename = require('gulp-rename'); -const { terminal } = require('@absolunet/terminal'); -const flow = require('~/helpers/flow'); -const paths = require('~/helpers/paths'); -const toolbox = require('~/helpers/toolbox'); -const util = require('~/helpers/util'); +const gulp = require('gulp'); +const imagemin = require('gulp-imagemin'); +const rename = require('gulp-rename'); +const flow = require('~/helpers/flow'); +const paths = require('~/helpers/paths'); +const toolbox = require('~/helpers/toolbox'); +const util = require('~/helpers/util'); module.exports = () => { @@ -44,15 +42,9 @@ module.exports = () => { flow.createTask('assets-images-highdensity', () => { return util.assetsProcess(paths.files.images2x, (stream) => { return stream - .pipe(toolbox.plumber()) - .pipe(gm((gmfile, done) => { - gmfile.identify((error, info) => { - if (error) { - terminal.error(error); - } - toolbox.gmOptimization(gmfile.resize('50%', '50%'), info); - done(null, gmfile); - }); + + .pipe(toolbox.jimp((Jimp, image) => { + image.scale(0.5, Jimp.RESIZE_BICUBIC); })) .pipe(imagemin()) diff --git a/packages/workflow/tasks/icons.js b/packages/workflow/tasks/icons.js index af4746f8..662c6ecd 100644 --- a/packages/workflow/tasks/icons.js +++ b/packages/workflow/tasks/icons.js @@ -4,16 +4,14 @@ 'use strict'; // const debug = require('gulp-debug'); -const gulp = require('gulp'); -const gm = require('gulp-gm'); -const gulpif = require('gulp-if'); -const imagemin = require('gulp-imagemin'); -const rename = require('gulp-rename'); -const { terminal } = require('@absolunet/terminal'); -const flow = require('~/helpers/flow'); -const paths = require('~/helpers/paths'); -const toolbox = require('~/helpers/toolbox'); -const util = require('~/helpers/util'); +const gulp = require('gulp'); +const gulpif = require('gulp-if'); +const imagemin = require('gulp-imagemin'); +const rename = require('gulp-rename'); +const flow = require('~/helpers/flow'); +const paths = require('~/helpers/paths'); +const toolbox = require('~/helpers/toolbox'); +const util = require('~/helpers/util'); module.exports = () => { @@ -37,12 +35,7 @@ module.exports = () => { return stream .pipe(toolbox.plumber()) - .pipe(gm((gmfile) => { - return gmfile - .define(`icon:auto-resize=${sizes.join(',')}`) - .setFormat('ico') - ; - }, { imageMagick: true })) + .pipe(toolbox.ico(sizes)) .pipe(rename(util.assetsRename())) ; @@ -83,13 +76,8 @@ module.exports = () => { return stream .pipe(toolbox.plumber()) - .pipe(gulpif(size !== 512, gm((gmfile, done) => { - gmfile.identify((error, info) => { - if (error) { - terminal.error(error); - } - done(null, toolbox.gmOptimization(gmfile.resize(size, size), info)); - }); + .pipe(gulpif(size !== 512, toolbox.jimp((Jimp, image) => { + image.resize(size, size, Jimp.RESIZE_BICUBIC); }))) .pipe(rename(util.assetsRename(`touch-${size}`))) @@ -128,13 +116,8 @@ module.exports = () => { return stream .pipe(toolbox.plumber()) - .pipe(gulpif(size !== 256, gm((gmfile, done) => { - gmfile.identify((error, info) => { - if (error) { - terminal.error(error); - } - done(null, toolbox.gmOptimization(gmfile.resize(size, size), info)); - }); + .pipe(gulpif(size !== 256, toolbox.jimp((Jimp, image) => { + image.resize(size, size, Jimp.RESIZE_BICUBIC); }))) .pipe(rename(util.assetsRename(`icon-${size}`))) @@ -186,20 +169,8 @@ module.exports = () => { return stream .pipe(toolbox.plumber()) - .pipe(gm((gmfile, done) => { - gmfile.identify((error, info) => { - if (error) { - terminal.error(error); - } - - const file = toolbox.gmOptimization(gmfile.resize(size[0], size[1]), info); - - if (name === 'wide') { - file.background('transparent').gravity('Center').extent(size[0], size[1]); - } - - done(null, file); - }); + .pipe(toolbox.jimp((Jimp, image) => { + image.contain(size[0], size[1], Jimp.RESIZE_BICUBIC); })) .pipe(rename(util.assetsRename(`tile-${name}`))) diff --git a/readme.md b/readme.md index 1196760e..265250b6 100644 --- a/readme.md +++ b/readme.md @@ -17,9 +17,8 @@ -## Requirements (All latest) - [Installation guide](documentation/requirements) +## Requirements - [Installation guide](documentation/requirements) - [Node.js](https://nodejs.org) ([nwayo CLI](https://www.npmjs.com/package/@absolunet/nwayo-cli)) -- [GraphicsMagick](http://www.graphicsmagick.org) / [ImageMagick](https://www.imagemagick.org) @@ -60,7 +59,7 @@ nwayo is HTML5 ready and uses [gulp](https://gulpjs.com) as a build system #### Other - Optimizes images via [gifsicle](https://www.lcdf.org/gifsicle), [MozJPEG](https://github.com/mozilla/mozjpeg), [optipng](http://optipng.sourceforge.net), [svgo](https://github.com/svg/svgo) -- Generates iconography via [GraphicsMagick](http://www.graphicsmagick.org), [ImageMagick](https://www.imagemagick.org) +- Generates iconography via [Jimp](https://github.com/oliver-moran/jimp), [to-ico](https://github.com/kevva/to-ico) diff --git a/test/fixtures/build/icons/site/favicon.ico b/test/fixtures/build/icons/site/favicon.ico index d3887467..c73afc46 100644 Binary files a/test/fixtures/build/icons/site/favicon.ico and b/test/fixtures/build/icons/site/favicon.ico differ diff --git a/test/fixtures/build/icons/site/icon-192.png b/test/fixtures/build/icons/site/icon-192.png index 4bc763d2..cc4b0d9c 100644 Binary files a/test/fixtures/build/icons/site/icon-192.png and b/test/fixtures/build/icons/site/icon-192.png differ diff --git a/test/fixtures/build/icons/site/icon-195.png b/test/fixtures/build/icons/site/icon-195.png index ae3aa362..712f805f 100644 Binary files a/test/fixtures/build/icons/site/icon-195.png and b/test/fixtures/build/icons/site/icon-195.png differ diff --git a/test/fixtures/build/icons/site/icon-196.png b/test/fixtures/build/icons/site/icon-196.png index 9e2c534e..e0951643 100644 Binary files a/test/fixtures/build/icons/site/icon-196.png and b/test/fixtures/build/icons/site/icon-196.png differ diff --git a/test/fixtures/build/icons/site/icon-228.png b/test/fixtures/build/icons/site/icon-228.png index 0b085221..0389067d 100644 Binary files a/test/fixtures/build/icons/site/icon-228.png and b/test/fixtures/build/icons/site/icon-228.png differ diff --git a/test/fixtures/build/icons/site/icon-64.png b/test/fixtures/build/icons/site/icon-64.png index 246de06a..c9cc552c 100644 Binary files a/test/fixtures/build/icons/site/icon-64.png and b/test/fixtures/build/icons/site/icon-64.png differ diff --git a/test/fixtures/build/icons/site/icon-96.png b/test/fixtures/build/icons/site/icon-96.png index 326af29f..6dc7bd08 100644 Binary files a/test/fixtures/build/icons/site/icon-96.png and b/test/fixtures/build/icons/site/icon-96.png differ diff --git a/test/fixtures/build/icons/site/tile-large.png b/test/fixtures/build/icons/site/tile-large.png index a9dce8ef..10cb22c2 100644 Binary files a/test/fixtures/build/icons/site/tile-large.png and b/test/fixtures/build/icons/site/tile-large.png differ diff --git a/test/fixtures/build/icons/site/tile-medium.png b/test/fixtures/build/icons/site/tile-medium.png index 733bd40c..bfa11f20 100644 Binary files a/test/fixtures/build/icons/site/tile-medium.png and b/test/fixtures/build/icons/site/tile-medium.png differ diff --git a/test/fixtures/build/icons/site/tile-small.png b/test/fixtures/build/icons/site/tile-small.png index c5e21063..5c642721 100644 Binary files a/test/fixtures/build/icons/site/tile-small.png and b/test/fixtures/build/icons/site/tile-small.png differ diff --git a/test/fixtures/build/icons/site/tile-wide.png b/test/fixtures/build/icons/site/tile-wide.png index f6f67dd7..1de50ecb 100644 Binary files a/test/fixtures/build/icons/site/tile-wide.png and b/test/fixtures/build/icons/site/tile-wide.png differ diff --git a/test/fixtures/build/icons/site/touch-114.png b/test/fixtures/build/icons/site/touch-114.png index 391045a1..8d443374 100644 Binary files a/test/fixtures/build/icons/site/touch-114.png and b/test/fixtures/build/icons/site/touch-114.png differ diff --git a/test/fixtures/build/icons/site/touch-120.png b/test/fixtures/build/icons/site/touch-120.png index 28926771..a462844e 100644 Binary files a/test/fixtures/build/icons/site/touch-120.png and b/test/fixtures/build/icons/site/touch-120.png differ diff --git a/test/fixtures/build/icons/site/touch-144.png b/test/fixtures/build/icons/site/touch-144.png index b1e00e6a..8013e37f 100644 Binary files a/test/fixtures/build/icons/site/touch-144.png and b/test/fixtures/build/icons/site/touch-144.png differ diff --git a/test/fixtures/build/icons/site/touch-152.png b/test/fixtures/build/icons/site/touch-152.png index 0e8d1617..f279bc48 100644 Binary files a/test/fixtures/build/icons/site/touch-152.png and b/test/fixtures/build/icons/site/touch-152.png differ diff --git a/test/fixtures/build/icons/site/touch-167.png b/test/fixtures/build/icons/site/touch-167.png index 31483d65..a6c2cc67 100644 Binary files a/test/fixtures/build/icons/site/touch-167.png and b/test/fixtures/build/icons/site/touch-167.png differ diff --git a/test/fixtures/build/icons/site/touch-180.png b/test/fixtures/build/icons/site/touch-180.png index d9f07b46..d275718b 100644 Binary files a/test/fixtures/build/icons/site/touch-180.png and b/test/fixtures/build/icons/site/touch-180.png differ diff --git a/test/fixtures/build/icons/site/touch-57.png b/test/fixtures/build/icons/site/touch-57.png index 9a3be33d..7e45684c 100644 Binary files a/test/fixtures/build/icons/site/touch-57.png and b/test/fixtures/build/icons/site/touch-57.png differ diff --git a/test/fixtures/build/icons/site/touch-72.png b/test/fixtures/build/icons/site/touch-72.png index eb8dda86..41c41d70 100644 Binary files a/test/fixtures/build/icons/site/touch-72.png and b/test/fixtures/build/icons/site/touch-72.png differ diff --git a/test/fixtures/build/icons/site/touch-76.png b/test/fixtures/build/icons/site/touch-76.png index 6f5ad1c7..553fcb49 100644 Binary files a/test/fixtures/build/icons/site/touch-76.png and b/test/fixtures/build/icons/site/touch-76.png differ