見出し画像

【リビルド】イラストを文字列で再表現


背景

プログラマーをやっています。champayaと申します💻

最近、「身の回りのものにある関数を通したら、別の表現ができるんじゃないか?」と考えつきました。ある関数=アルゴリズムです。

個人的には、汎用性もあるし、割と面白い考えだと思っています。

それではやっていきましょう。何卒何卒。

イラスト→文字列

イラスト全体を文字列のみで再表現します。イラストの各ピクセルを文字列に置き換えるようなイメージです。

元の画像はこちら。ずとまよさんの「綺羅キラー」サムネです。

「ずっと真夜中でいいのに。」の著作権はとてもおおらかなので画像使わせてもらってます。
異議申し立てがある場合は、すぐに画像の削除処理をさせていただきます。

https://zutomayo.net/legal/

手順

以下の手順で処理します:

  1. 画像を縮小:画像を小さくして処理を軽くします。

  2. 文字を割り当て:画像の各ピクセルに、好きな文字列からランダムに文字を配置します。

  3. 色を適用:元の画像の色を文字に反映させます。

  4. 新しい画像を生成:文字で描かれた新しい画像を作成して保存します。

これで、元画像が好きな文字で描かれた画像として再表現されます。

使用するライブラリ

  • random:文字をランダムに選ぶため

  • cv2 (OpenCV):画像の読み込みやリサイズ

  • numpy:画像データを効率的に扱うため

  • PIL (Pillow):新しい画像を作成し、文字を描画

  • pathlib:ファイルパスの操作

  • argparse:コマンドライン引数の処理

import random
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont
import pathlib
import argparse

プログラムの流れ

1. 画像の読み込みと縮小

まず、指定した画像を読み込み、画像を縮小する関数を作ります。

def process_image(image_path, scale_factor):
    # 画像ファイルを読み込む
    image = cv2.imread(image_path)

    # 新しい幅と高さを計算
    new_width = image.shape[1] // scale_factor
    new_height = image.shape[0] // scale_factor

    # 画像をリサイズ
    resized_image = cv2.resize(image, (new_width, new_height), interpolation=cv2.INTER_AREA)

    # BGRからRGBへ変換
    compressed_image_rgb = cv2.cvtColor(resized_image, cv2.COLOR_BGR2RGB)

    # 画像のRGB配列を取得
    rgb_array = np.array(compressed_image_rgb)
    return rgb_array

2. 文字の割り当て

次に、画像の各ピクセルにランダムな文字を割り当てる関数を作ります。

def assign_random_characters(height, width, characters):
    return [[random.choice(characters) for _ in range(width)] for _ in range(height)]

3. メイン処理

`main` 関数では、以下の順序で処理を実行します。

  1. インポートするフォルダから `jpg` ファイルを取得

  2. 画像に対してランダムに文字列を割り当てる関数を実行

  3. 文字列を配置するためのベースとなる画像を作成(背景色はグレー)

  4. フォントをロード(等幅フォントを使用してください)

  5. 文字列をベース画像に配置

  6. アウトプット用のフォルダに `png` として保存

def main(args):
    input_list = list(pathlib.Path(args.input_dir).glob("*.jpg"))

    for input_path in input_list:
        rgb_values = process_image(input_path, args.scale_factor)

        # 画像のサイズを取得
        height, width, _ = rgb_values.shape

        # ランダムに文字を割り当てる
        randomized_display_strings = assign_random_characters(height, width, list(args.characters))

        # 画像を作成(背景をグレーに設定)
        im = Image.new("RGB", (width * args.image_width_multiplier, height * args.image_height_multiplier), (200, 200, 200))
        draw = ImageDraw.Draw(im)

        # 日本語フォントのロード
        font = ImageFont.truetype(args.font_path, args.font_size)

        # 描画処理
        x, y = 0, 0
        for i, line in enumerate(randomized_display_strings):
            for j, char in enumerate(line):
                # RGB値を取得し、文字の色に設定
                R, G, B = rgb_values[i, j]
                color = (int(R), int(G), int(B))  # RGB値をそのまま文字の色に使用
                # テキストを描画
                draw.text((x + j * args.image_width_multiplier, y), char, fill=color, font=font)
            y += args.font_size  # 行間を含めたY座標の調整

        # ファイルに出力
        output_file_path = pathlib.Path(args.output_dir) / (input_path.stem + ".png")
        im.save(output_file_path)

4. ファイル実行時の処理

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="画像を文字化して処理するプログラム")
    
    # コマンドライン引数の設定
    parser.add_argument('--input_dir', type=str, default="./_image_color_input", help="入力画像のディレクトリ")
    parser.add_argument('--output_dir', type=str, default="./_image_color_output", help="出力画像のディレクトリ")
    parser.add_argument('--font_path', type=str, default='C:/Windows/Fonts/msgothic.ttc', help="日本語フォントのパス")
    parser.add_argument('--font_size', type=int, default=10, help="フォントサイズ")
    parser.add_argument('--image_width_multiplier', type=int, default=10, help="文字の幅を調整する倍率")
    parser.add_argument('--image_height_multiplier', type=int, default=10, help="文字の高さを調整する倍率")
    parser.add_argument('--characters', type=str, default="ずっと真夜中でいいのに。", help="ランダムに使用する文字列")
    parser.add_argument('--scale_factor', type=int, default=10, help="解像度を下げる値")

    # 引数を解析してメイン関数を呼び出す
    args = parser.parse_args()
    main(args)

実際に出力された画像

よーーーーーく見てみると文字列(「ずっと真夜中でいいのに。」)で画像ができてることがわかります。

カラー

フォントサイズや解像度の調整を工夫すると、さらに繊細な画像の作成も可能です。

似たようなプログラムでモノクロ画像も作れます。

モノクロ

カスタマイズ可能な引数

プログラムはコマンドライン引数でさまざまな設定が可能です:

  • `--input_dir`:入力画像のフォルダを指定(デフォルト:`./_image_color_input`)

  • `--output_dir`:出力画像のフォルダを指定(デフォルト:`./_image_color_output`)

  • `--font_path`:使用するフォントのパス(デフォルト:`C:/Windows/Fonts/msgothic.ttc`)

  • `--font_size`:フォントサイズを指定(デフォルト:`10`)

  • `--image_width_multiplier`:文字の横方向の間隔(デフォルト:`10`)

  • `--image_height_multiplier`:文字の縦方向の間隔(デフォルト:`10`)

  • `--characters`:使用する文字列を指定(デフォルト:`"ずっと真夜中でいいのに。"`)

  • `--scale_factor`:画像の縮小倍率を指定(デフォルト:`10`)

まとめ

このプログラムを使えば、普段の画像を一味違ったアート作品に変身させることができます!

アルゴリズムでの再表現、これからも続けていきたいです。。。。

ぜひ、Instagramもフォローしていただけると嬉しいです!!!

https://www.instagram.com/zutomayo_program_tai/

いいなと思ったら応援しよう!