diff --git a/poptimal.js b/poptimal.js index 7a2f1a7..ff2a093 100644 --- a/poptimal.js +++ b/poptimal.js @@ -11,13 +11,14 @@ const xmlns = "http://www.w3.org/2000/xmlns/"; const xlinkns = "http://www.w3.org/1999/xlink"; const svgns = "http://www.w3.org/2000/svg"; -import {RADIUS_OPTS, DotMaker} from './src/components/dots.js'; +import {RADIUS_OPTS, RADIUS_DESC, DotMaker} from './src/components/dots.js'; import {PALETTES, ColourNamer} from './src/components/palettes.js'; const CELL = 10; const MAG = 2; const WIDTH = 20; const HEIGHT = WIDTH; +const VISIBLE_DOG = 1000; function randomise_params() { const palette_name = random.choice(Array.from(PALETTES.keys())); @@ -52,29 +53,54 @@ async function get_histogram(imgfile) { function parse_histogram(convert_out) { - const colour_re = /(\d+): \(\d+,\d+,\d+,\d+\) #([A-F0-9]+) /; + const colour_re = /(\d+): \(\d+,\d+,\d+,\d+\) (#[A-F0-9]+) /; const colours = new Map(); convert_out.split("\n").forEach((l) => { const m = l.match(colour_re); if( m ) { - console.log(m[1], m[2]); - const colour = m[2].substring(0, 6); + const colour = m[2].substring(0, 7); colours.set(colour, Number(m[1])); - } else { - console.log(`no match ${l}`); } }); return new Map([...colours].sort((a, b) => b[1] - a[1])); } +function colour_visible(hist, colour) { + const hexcolour = colour.formatHex().toUpperCase(); + console.log(colour, hexcolour, hist.get(hexcolour)); + return hist.get(hexcolour) > VISIBLE_DOG; +} -function image_description(namer, params) { - const bgc = namer.colour_to_text(params.background); - const dotc = params.patterns.map((p) => namer.colour_to_text(p.colour)); - const a = bgc.match(/^[aeiou]/) ? 'an' : 'a'; - return `A pattern of ${dotc[0]} and ${dotc[1]} dots on ${a} ${bgc} background`; +function image_description(namer, params, histogram) { + const colours = [ + params.background, + params.patterns[0].colour, + params.patterns[1].colour, + ]; + const i_vis = [0, 1, 2].filter((i) => colour_visible(histogram, colours[i])); + const named_colours = i_vis.map((i) => namer.colour_to_text(colours[i])); + const gradients = i_vis.map((i) => { + if( i > 0 ) { + return RADIUS_DESC[params.patterns[i - 1].f]; + } else { + return ''; + } + }); + if( named_colours.length == 1 ) { + return `A solid field of ${named_colours[0]}`; + } + if( named_colours.length > 1 ) { + const bgc = named_colours[0]; + const a = bgc.match(/^[aeiou]/) ? 'an' : 'a'; + const dot_desc = named_colours.slice(1); + const gs = gradients.slice(1); + const pattern_desc = dot_desc.map((d, i) => `${d} dots ${gs[i]}`); + const patterns = pattern_desc.join(' and '); + return `A pattern of ${patterns} on ${a} ${bgc} background`; + } + return ""; } @@ -154,21 +180,6 @@ async function post_image(image, alt_text, cf) { } -function survey_pixels(pngData) { - const pixbuf = pngData.pixels; - const pixels = Array.from(pixbuf); - const colours = {}; - for( let i = 0; i += 3; i < pixels.length ) { - const hex = `${pixels[i]},${pixels[i + 1]},${pixels[i + 2]}`; - if( ! hex in colours ) { - colours[hex] = 0; - } - colours[hex]++; - } - console.log(colours); - -} - async function main() { const argv = yargs(hideBin(process.argv)) @@ -186,7 +197,6 @@ async function main() { const imgfile = cf['working_dir'] + '/' + fn; const params = randomise_params(); - console.log(params.palette); const colourf = params.palette === 'grayscale' ? cf['grayscale'] : cf['colour']; const namer = new ColourNamer(); @@ -212,11 +222,10 @@ async function main() { // generate the alt_text last to check the image file histogram // so we don't include obscured colours const hist = await get_histogram(imgfile); - console.log(hist); - const alt_text = image_description(namer, params, imgfile); + const alt_text = image_description(namer, params, hist); - console.log(imgfile); console.log(alt_text); + console.log(imgfile); if( cf['base_url'] ) { await post_image(imgfile, alt_text, cf); } diff --git a/src/components/dots.js b/src/components/dots.js index 03d2e9e..d767b6a 100644 --- a/src/components/dots.js +++ b/src/components/dots.js @@ -16,6 +16,21 @@ const RADIUS_OPTS = [ "noise", ]; +const RADIUS_DESC = { + "const": "of constant size", + "right": "getting larger towards the left", + "left": "getting larger towards the left", + "up": "getting larger towards the top", + "down": "getting larger towards the bottom", + "right-up": "getting larger towards the upper right", + "right-down": "getting larger towards the lower right", + "left-up": "getting larger towards the upper left", + "left-down": "getting larger towards the lower left", + "in": "getting larger in the centre", + "out": "getting larger at the edges", + "noise": "of random sizes", +} + function distance(dx, dy) { return Math.sqrt(dx ** 2 + dy ** 2); } @@ -92,6 +107,6 @@ class DotMaker { } } -export { RADIUS_OPTS, DotMaker }; +export { RADIUS_OPTS, RADIUS_DESC, DotMaker };