目次
アスキーアートといえば、日本のネット界の1時代を築いた文化。
そんなアスキーアートを任意の文字と任意の画像から誰でも作れるプログラムをhtml/JavaScriptで実装してみました。
たとえば、こんなりんごの画像を選択し、
テキストエリアに「This is an apple」と入力すると…
このようにりんごの画像が「This is an apple」という文言の中に含まれる文字のみを使って、アスキーアートで描画されます。
ズームしてよーーーくみると…
たしかに、「This is an apple」に含まれる文字しか使っていません。
以下のような手順で実現しています。
function getSortedCharactersByBrightness(characters) { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); const brightnessValues = []; canvas.width = 100; canvas.height = 100; for (let i = 0; i < characters.length; i++) { ctx.fillStyle = "white"; ctx.fillRect(0, 0, 100, 100); ctx.fillStyle = "black"; ctx.font = "80px serif"; ctx.fillText(characters[i], 10, 70); const imageData = ctx.getImageData(0, 0, 100, 100); let darkPixels = 0; for (let j = 0; j < imageData.data.length; j += 4) { const r = imageData.data[j]; const g = imageData.data[j + 1]; const b = imageData.data[j + 2]; if (r < 128 && g < 128 && b < 128) { darkPixels++; } } brightnessValues.push({ char: characters[i], brightness: darkPixels }); } brightnessValues.sort((a, b) => a.brightness - b.brightness); return brightnessValues.map(val => val.char).join(''); }
上記のように、一度canvasを作り(ただし画面には表示しない)、
大きめの文字で1文字ずつ描画します。
イメージ: 「This is a pen」の「T」をcanvasに描画
そしてこの見えないcanvas上の全てのピクセルデータを走査し、色のついている面積の明るさ(R/G/Bチャンネルの合計値)を計算すると、一文字ごとの「明るさ」の合計値が計算できるので、明るい順でソートしておきます。
たとえば、「赤い花」という文字が入力された場合、「赤」「い」「花」のそれぞれの文字の明るさは
のようになるので、「花」→「赤」→「い」の順で明るさの整列ができます。
ステップ1でユーザーの入力した文字を1文字ずつ見えないcanvasに描画したのと同じように、ユーザーが選択した画像を見えないcanvas上に一度描画し、全てのピクセルを走査して、それぞれの明るさを計算します。
画像のそれぞれのピクセルの明るさに最も近似する明るさを持つ文字を使って、
描画していきます。
CODEPENにアップロードしてあるので、どなたでもご自由にお試しいただくことができます。
また、このソースコードは誰でも自由に使用することが可能です。