Browse Source

chore: switch to Sharp to improve legibility of small icons

tophf 5 years ago
parent
commit
9e661e7af7
3 changed files with 224 additions and 470 deletions
  1. 35 22
      gulpfile.js
  2. 1 1
      package.json
  3. 188 447
      yarn.lock

+ 35 - 22
gulpfile.js

@@ -6,7 +6,7 @@ const gulpFilter = require('gulp-filter');
 const uglify = require('gulp-uglify');
 const plumber = require('gulp-plumber');
 const yaml = require('js-yaml');
-const Jimp = require('jimp');
+const Sharp = require('sharp');
 const { isProd } = require('@gera2ld/plaid/util');
 const spawn = require('cross-spawn');
 const i18n = require('./scripts/i18n');
@@ -82,29 +82,42 @@ async function manifest() {
 }
 
 async function createIcons() {
+  const ALPHA = .5;
   const dist = `${DIST}/public/images`;
   await fs.mkdir(dist, { recursive: true });
-  const icon = await Jimp.read('src/resources/icon.png');
-  const promises = [];
-  promises.push(...[
-    48, 128,
-  ].map(size => icon.clone().resize(size, size).write(`${dist}/icon${size}.png`)));
-  const gray = icon.clone().greyscale();
-  const transparent = icon.clone().fade(0.5);
-  promises.push(...[
-    19, 32, 38,
-  ].flatMap(size => [
-    icon.clone().resize(size, size).write(`${dist}/icon${size}.png`),
-    gray.clone().resize(size, size).write(`${dist}/icon${size}b.png`),
-    transparent.clone().resize(size, size).write(`${dist}/icon${size}w.png`),
-  ]));
-  const handle16 = image => image.clone().resize(18, 18).crop(1, 2, 16, 16);
-  promises.push(...[
-    handle16(icon).write(`${dist}/icon16.png`),
-    handle16(gray).write(`${dist}/icon16b.png`),
-    handle16(transparent).write(`${dist}/icon16w.png`),
-  ])
-  return Promise.all(promises);
+  const icon = Sharp('src/resources/icon.png');
+  const gray = icon.clone().grayscale();
+  const transparent = icon.clone().composite([{
+    input: Buffer.from([255, 255, 255, 256 * ALPHA]),
+    raw: { width: 1, height: 1, channels: 4 },
+    tile: true,
+    blend: 'dest-in',
+  }]);
+  const types = [
+    ['', icon],
+    ['b', gray],
+    ['w', transparent],
+  ];
+  const handle = (size, type = '', image = icon) => {
+    let res = image.clone().resize({ width: size });
+    if (size < 48) res = res.sharpen(size < 32 ? .5 : .25);
+    return res.toFile(`${dist}/icon${size}${type}.png`);
+  };
+  const handle16 = async ([type, image]) => {
+    const res = image.clone()
+    .resize({ width: 18 })
+    .sharpen(.5, 0)
+    .extract({ left: 1, top: 2, width: 16, height: 16 });
+    // darken the outer edge
+    return res.composite([{ input: await res.toBuffer(), blend: 'over' }])
+    .toFile(`${dist}/icon16${type}.png`);
+  };
+  return Promise.all([
+    handle(48),
+    handle(128),
+    ...types.map(handle16),
+    ...[19, 32, 38].flatMap(size => types.map(t => handle(size, ...t))),
+  ]);
 }
 
 /**

+ 1 - 1
package.json

@@ -38,10 +38,10 @@
     "gulp-plumber": "^1.1.0",
     "gulp-uglify": "^3.0.2",
     "husky": "^4.2.3",
-    "jimp": "^0.16.1",
     "js-yaml": "^3.13.1",
     "jsdom": "^16.2.1",
     "plugin-error": "^1.0.0",
+    "sharp": "^0.26.2",
     "tape": "^4.13.2",
     "through2": "^3.0.1",
     "vinyl": "^2.1.0",

File diff suppressed because it is too large
+ 188 - 447
yarn.lock


Some files were not shown because too many files changed in this diff