YOGO
MANAGEMENT
OFFICE
  • SERVICES
  • WORKS
  • RESEARCH
  • ABOUT US
  • CONTACT
Ascii Art Generator

Ascii Art Generator

YOGO
YOGO
TechVisuals
2023/11/30

目次

  • つくったもの
  • 仕組み
  • ステップ1: 与えられた文字の配列を、文字の明るさ順に並び替える
  • ステップ2-3: ユーザーが画像を選択した際に、画像を見えないcanvas上に描画し、それぞれのピクセルの明るさを計算する
  • ステップ4: ユーザーが入力した文字列を使って、画像を再構築する
  • デモ

つくったもの

アスキーアートといえば、日本のネット界の1時代を築いた文化。

そんなアスキーアートを任意の文字と任意の画像から誰でも作れるプログラムをhtml/JavaScriptで実装してみました。

たとえば、こんなりんごの画像を選択し、

テキストエリアに「This is an apple」と入力すると…

このようにりんごの画像が「This is an apple」という文言の中に含まれる文字のみを使って、アスキーアートで描画されます。

ズームしてよーーーくみると…

たしかに、「This is an apple」に含まれる文字しか使っていません。

仕組み

以下のような手順で実現しています。

  1. ユーザーが入力した文字の中から重複した文字を取り除き、文字の明るさ(=密度)順に並び替える
  2.  ユーザーが画像を選択
  3. 画像のビットマップ情報を取得する必要があるため、canvasを作成し、canvas上に画像を描画する(ただし、canvasそのものは表示しない)
  4. 3.で作成した仮想のcanvas上のピクセルデータを読み、1. でソート済みの文字を使って、明るい場所には明るい文字を置いていく

ステップ1: 与えられた文字の配列を、文字の明るさ順に並び替える

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(&apos;&apos;);
}

上記のように、一度canvasを作り(ただし画面には表示しない)、
大きめの文字で1文字ずつ描画します。

イメージ: 「This is a pen」の「T」をcanvasに描画

そしてこの見えないcanvas上の全てのピクセルデータを走査し、色のついている面積の明るさ(R/G/Bチャンネルの合計値)を計算すると、一文字ごとの「明るさ」の合計値が計算できるので、明るい順でソートしておきます。

たとえば、「赤い花」という文字が入力された場合、「赤」「い」「花」のそれぞれの文字の明るさは

  • 赤: 1388
  • い: 592
  • 花: 1513

のようになるので、「花」→「赤」→「い」の順で明るさの整列ができます。

ステップ2-3: ユーザーが画像を選択した際に、画像を見えないcanvas上に描画し、それぞれのピクセルの明るさを計算する

ステップ1でユーザーの入力した文字を1文字ずつ見えないcanvasに描画したのと同じように、ユーザーが選択した画像を見えないcanvas上に一度描画し、全てのピクセルを走査して、それぞれの明るさを計算します。

ステップ4: ユーザーが入力した文字列を使って、画像を再構築する

画像のそれぞれのピクセルの明るさに最も近似する明るさを持つ文字を使って、
描画していきます。

デモ

CODEPENにアップロードしてあるので、どなたでもご自由にお試しいただくことができます。

また、このソースコードは誰でも自由に使用することが可能です。

← Back to Research