Аткінсонія
Jun. 12th, 2025 04:15 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
"Компактні" Мокінтоши перестали мати чорно-білі екрани лише 1993 року, що є вкрай смішно, тому що їх лінійка "професійних" Мокінтошів ІІ отримала кольори ув 1987. NeXT ув 1988 вийшов з 2-бітним монітором (ч/б + 2 варіянти сірого), про що ув одному зі старих інтерв'ю Джобса останній розповідав як газети тоді писали що він таємно ненавидить кольори і, коли має для того владу, робить лише монохромні комп'ютери.
(До речі, оригінальний посібник по Мокінтошу ІІ виглядав гарною coffee table книжкою (конь цепта маловідомий у Центрально-Східній Європі), випадкове досягнення яке Епл спромоглася повторити ніколи, навіть після повернення Джобса.)
Мокінтош ув 1984 комплектувавсь безоплатним MacPaint'ом, який трохи пізніше Майкрософта злизала собі для віндюка. Для 1-бітних екранів симулювати відтінки сірого ув MacPaint'і можна було тільки за допомогою дізерінґу. Найвідоміший алгоритм--Floyd-Steinberg (FS)--був винайдений ув 1974, але Аткінсон, якого автор книжки Revolution in the valley називає єдиним дорослим ув команді Мокінтошу, вважав FS малоконтрастним.
Коли стало відомо що Аткінсон помер, на HN з'явився лінка на бовзерний емулятора його алгоритму від якогось угорця, який ховається від Орбана ув Ландані.
Якість мене вразила:


Напевно це можна робити ув лайнаксі з командного рядка? На жаль,
ні. Опція -⁠dither
ув ImageMagick про Аткінсона
не знає (слушайтє пєсню Валєнкі). pamditherbw (з netpbm) знає, але
результат засмучує:

Угорська демо працює так:
- створюється Canvas з розміром зображення оригінального кольорового;
- зображення копіюється на Canvas;
- з Canvas'у читаються пікселі ув форматі ImageData;
- ImageData модифікується;
- Результат знову копіюється на Canvas;
- з Canvas'у експортується нове чб-зображення ув форматі png.
Всі пункти, окрім 4, підтримуються власно бовзером та вимагають жодних зусиль.
Хоча угорська демо написана ув темні часи кофіскрипта, траспайлер останнього друкує читабельного джаваскрипта. Скомбінувавши зміст до 1ї хфункції
export default function(imagedata) {
let threshold = i => (i <= 128) ? 0 : 255
let luminance = function(imagedata) {
var i, j, pixels, ref;
pixels = imagedata.data;
for (i = j = 0, ref = pixels.length; j <= ref; i = j += 4) {
// luminance: red x 0.3 + green x 0.59 + blue x 0.11
pixels[i] = pixels[i + 1] = pixels[i + 2] = parseInt(pixels[i] * 0.3 + pixels[i + 1] * 0.59 + pixels[i + 2] * 0.11, 10);
}
return imagedata;
}
let dither = function(imagedata) {
var err, i, j, mono, neighbours, one, pixels, ref, w;
pixels = imagedata.data;
w = imagedata.width;
for (i = j = 0, ref = pixels.length; j <= ref; i = j += 4) {
neighbours = [i + 4, i + 8, i + (4 * w) - 4, i + (4 * w), i + (4 * w) + 4, i + (8 * w)];
mono = threshold(pixels[i]);
err = parseInt((pixels[i] - mono) / 8, 10);
pixels[i] = mono;
for (one in neighbours) {
pixels[neighbours[one]] += err;
}
pixels[i + 1] = pixels[i + 2] = pixels[i];
}
return imagedata;
}
return dither(luminance(imagedata))
}
залишається лише прикрутити її до Canvas. (Уважний читач помітить зайві змінні ув циклах, courtesy of транспайлера.)
Спочатку я чомусь вирішив що то є робота для Puppeteer. Це була велика помилка. Кожного разу коли я намагаюся притулити його до чогось, закінчується це невгамовним бажанням міцно потримати авторів Puppeteer ойпіай за горло. Кривий скрипта врешті запрацював, але користуватися їм я не раджу.
Потім я згадав про шматки DOM, які нарід багато років (марно) намагаються портувати до ноуда. Певно, Canvas має бути там давно? Виявляється, так, контора яка пише Вордпреса, роздає свою реалізацію всім охочим. (Її дуже складно знайти--1й хіт на npmjs.com на кейворда "кенвес".)
З вордпресівською бібліотекою, безглуздий мотлох Puppeteer зменшується до
function dither(img, algo) {
let cnvas = canvas.createCanvas(img.width, img.height)
let ctx = cnvas.getContext('2d')
ctx.drawImage(img, 0, 0)
let imagedata = ctx.getImageData(0, 0, img.width, img.height)
ctx.putImageData(algo(imagedata), 0, 0)
return cnvas.createPNGStream()
}
IRL, щоб показувати прогреса ув %, там є трохи більше рядків, але мінімалізм мене тішить. Щоб подивитися на життя ув 1984, для ноуда 22:
$ npm -g i atkinson
$ atkinson file.jpg > 1.png