/** * Identicon generator * https://en.wikipedia.org/wiki/Identicon */ import * as p from "pureimage"; import gen from "random-seed"; const size = 128; // px const n = 5; // resolution const margin = size / 4; const colors = [ [ "#eb6f92", "#b4637a" ], [ "#f6c177", "#ea9d34" ], [ "#ebbcba", "#d7827e" ], [ "#9ccfd8", "#56949f" ], [ "#c4a7e7", "#907aa9" ], [ "#eb6f92", "#f6c177" ], [ "#eb6f92", "#ebbcba" ], [ "#eb6f92", "#31748f" ], [ "#eb6f92", "#9ccfd8" ], [ "#eb6f92", "#c4a7e7" ], [ "#f6c177", "#eb6f92" ], [ "#f6c177", "#ebbcba" ], [ "#f6c177", "#31748f" ], [ "#f6c177", "#9ccfd8" ], [ "#f6c177", "#c4a7e7" ], [ "#ebbcba", "#eb6f92" ], [ "#ebbcba", "#f6c177" ], [ "#ebbcba", "#31748f" ], [ "#ebbcba", "#9ccfd8" ], [ "#ebbcba", "#c4a7e7" ], [ "#31748f", "#eb6f92" ], [ "#31748f", "#f6c177" ], [ "#31748f", "#ebbcba" ], [ "#31748f", "#9ccfd8" ], [ "#31748f", "#c4a7e7" ], [ "#9ccfd8", "#eb6f92" ], [ "#9ccfd8", "#f6c177" ], [ "#9ccfd8", "#ebbcba" ], [ "#9ccfd8", "#31748f" ], [ "#9ccfd8", "#c4a7e7" ], [ "#c4a7e7", "#eb6f92" ], [ "#c4a7e7", "#f6c177" ], [ "#c4a7e7", "#ebbcba" ], [ "#c4a7e7", "#31748f" ], [ "#c4a7e7", "#9ccfd8" ] ]; const actualSize = size - margin * 2; const cellSize = actualSize / n; const sideN = Math.floor(n / 2); /** * Generate buffer of an identicon by seed */ export function genIdenticon(seed, stream) { const rand = gen.create(seed); const canvas = p.make(size, size, undefined); const ctx = canvas.getContext("2d"); const bgColors = colors[rand(colors.length)]; const bg = ctx.createLinearGradient(0, 0, size, size); bg.addColorStop(0, bgColors[0]); bg.addColorStop(1, bgColors[1]); ctx.fillStyle = bg; ctx.beginPath(); ctx.fillRect(0, 0, size, size); ctx.fillStyle = "#ffffff"; // side bitmap (filled by false) const side = new Array(sideN); for(let i = 0; i < side.length; i++){ side[i] = new Array(n).fill(false); } // 1*n (filled by false) const center = new Array(n).fill(false); for(let x = 0; x < side.length; x++){ for(let y = 0; y < side[x].length; y++){ side[x][y] = rand(3) === 0; } } for(let i = 0; i < center.length; i++){ center[i] = rand(3) === 0; } // Draw for(let x = 0; x < n; x++){ for(let y = 0; y < n; y++){ const isXCenter = x === (n - 1) / 2; if (isXCenter && !center[y]) continue; const isLeftSide = x < (n - 1) / 2; if (isLeftSide && !side[x][y]) continue; const isRightSide = x > (n - 1) / 2; if (isRightSide && !side[sideN - (x - sideN)][y]) continue; const actualX = margin + cellSize * x; const actualY = margin + cellSize * y; ctx.beginPath(); ctx.fillRect(actualX, actualY, cellSize, cellSize); } } return p.encodePNGToStream(canvas, stream); }