0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Jasmine TeaAdvent Calendar 2023

Day 22

Jasmine Tea でサンタの絵文字🎅を表示したい

Last updated at Posted at 2023-12-18

この記事は、 Jasmine Tea アドベントカレンダー 2023 の第22日目です。

こんにちは!Jasmine Tea の開発に参加している松尾です。

なんとなく、季節柄か Jasmine Tea でサンタ🎅を表示したいと思ったのでやってみました。

Jasmine Tea には、PIC パターンという仕組みがあります。これは 16x16 のイメージデータが予めいくつも登録してあり、PIC パターンの番号を指定するだけで登録済みのイメージを画面に表示することができる仕組みです。これより高次の機能であるスプライトやアニメーションの元になっています。

また、Jasmine Tea のユーザーは独自の PIC パターンを登録することもできます。これには data 命令を使うようです。下記のような感じです。

Jasmine Tea のドキュメントからの抜粋

p@=[]
for i=0 to 255
  read p@[i]
next
def pic 532,p@
put (100,100),532
end
data -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
data -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
data -1,-1,-1, 3, 3,-1,-1,-1,-1,-1,-1, 3, 3,-1,-1,-1
data -1,-1, 3, 3, 3, 3,-1,-1,-1,-1, 3, 3, 3, 3,-1,-1
data -1,-1, 3, 3, 3, 3, 3,-1,-1, 3, 3, 3, 3, 3,-1,-1
data -1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,-1
data -1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,-1
data -1,-1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,-1,-1
data -1,-1,-1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,-1,-1,-1
data -1,-1,-1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,-1,-1,-1
data -1,-1,-1,-1, 3, 3, 3, 3, 3, 3, 3, 3,-1,-1,-1,-1
data -1,-1,-1,-1,-1, 3, 3, 3, 3, 3, 3,-1,-1,-1,-1,-1
data -1,-1,-1,-1,-1,-1, 3, 3, 3, 3,-1,-1,-1,-1,-1,-1
data -1,-1,-1,-1,-1,-1,-1, 3, 3,-1,-1,-1,-1,-1,-1,-1
data -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
data -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1

なるほど。data から 256 個のピクセルを配列に読んで def pic 命令で登録するわけですね。Jasmine Tea で使用できるカラーパレットはあまり多くないので、色のマッピングをしてあげないといけないようですね。

js でチャチャッとスクリプトを書いてマッピングできるようにしてみましょう。

interface color {
    r: number,
    g: number,
    b: number,
}

const colors: { [key: number]: color } = {
    0: { r: 0, g: 0, b: 0 },
    1: { r: 0, g: 0, b: 255 },
    2: { r: 255, g: 0, b: 0 },
    3: { r: 255, g: 0, b: 255 },
    4: { r: 0, g: 255, b: 0 },
    5: { r: 0, g: 255, b: 255 },
    6: { r: 255, g: 255, b: 0 },
    7: { r: 255, g: 255, b: 255 },
    8: { r: 119, g: 119, b: 119 },
    9: { r: 0, g: 0, b: 170 },
    10: { r: 170, g: 0, b: 0 },
    11: { r: 170, g: 0, b: 170 },
    12: { r: 0, g: 170, b: 0 },
    13: { r: 0, g: 170, b: 170 },
    14: { r: 170, g: 170, b: 0 },
    15: { r: 170, g: 170, b: 170 },
    16: { r: 77, g: 129, b: 166 },
    17: { r: 78, g: 60, b: 60 },
    18: { r: 86, g: 98, b: 208 },
    19: { r: 87, g: 164, b: 254 },
    20: { r: 97, g: 166, b: 75 },
    21: { r: 124, g: 210, b: 207 },
    22: { r: 138, g: 218, b: 255 },
    23: { r: 139, g: 131, b: 129 },
    24: { r: 142, g: 76, b: 80 },
    25: { r: 152, g: 128, b: 248 },
    26: { r: 161, g: 112, b: 142 },
    27: { r: 172, g: 148, b: 124 },
    28: { r: 198, g: 192, b: 192 },
    29: { r: 205, g: 217, b: 59 },
    30: { r: 210, g: 191, b: 161 },
    31: { r: 238, g: 146, b: 43 },
    32: { r: 240, g: 112, b: 182 },
    33: { r: 245, g: 84, b: 64 },
    34: { r: 248, g: 157, b: 156 },
    35: { r: 249, g: 232, b: 216 },
    36: { r: 250, g: 205, b: 80 },
    37: { r: 251, g: 232, b: 42 },
};

function getClosestColorNumber(c: color): number {
    let smallestDiff = 255 * 3;
    let ret = 0;
    for (const n in colors) {
        const target = colors[n];
        const diff =
            Math.abs(c.r - target.r)
            + Math.abs(c.g - target.g)
            + Math.abs(c.b - target.b);
        if (diff < smallestDiff) {
            smallestDiff = diff;
            ret = parseInt(n, 10);
        }
    }
    return ret;
}

あとは画像データを Jasmine Tea の data 命令に変換してあげれば良さそうです。今回は便利そうな Jimp というライブラリを使いました。

(async () => {
    const j = await Jimp.read(args[2]);
    const result: number[][] = [];

    for (let y = 0; y < 32; y++) {
        result.push([]);
        for (let x = 0; x < 32; x++) {
            const c = j.getPixelColor(x, y);
            const rgb = Jimp.intToRGBA(c);
            const colorNumber = getClosestColorNumber(rgb);
            result[y].push(colorNumber);
        }
    }

    // Top left                                                                                                                                                    
    for (let y = 0; y < 16; y++) {
        console.log(`data ${result[y].slice(0, 16).join(',')}`);
    }
    // Top right                                                                                                                                                   
    for (let y = 0; y < 16; y++) {
        console.log(`data ${result[y].slice(16, 32).join(',')}`);
    }
    // Bottom left                                                                                                                                                 
    for (let y = 16; y < 32; y++) {
        console.log(`data ${result[y].slice(0, 16).join(',')}`);
    }
    // Bottom right                                                                                                                                                
    for (let y = 16; y < 32; y++) {
        console.log(`data ${result[y].slice(16, 32).join(',')}`);
    }

})();

アルファチャンネルの処理をしてないので、透明なところの表現ができてないですが、まあいいでしょう。こんな感じでJasmine Tea でサンタクロースを表示することができました〜

それでは、メリークリスマス🎅

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?