MSX1風画像エラーチェックツール

MSX1風画像エラーチェックツール

MSX1風フェイクゲーム動画の素材画像作成向けに横8ドットに3色以上の色が使われていないか、全体で16色を超えていないかを調べるエラーチェッカーをpythonで作ってみていた。

とりあえず python dotartcheck.py hoge.png -m で動くはず。エラー個所の図示やログを出力する。

import argparse
from pathlib import Path
from PIL import Image, ImageEnhance


def check(img: Image, output_img: Image, check_ng_color: tuple) -> list:
    """
    横8ドット内2色チェックお及び全体色数カウント
    :param img: チェックする画像
    :param output_img: チェックNG部分を描画する画像
    :param check_ng_color: NG色
    :return: 使用色の配列
    """
    all_colors = {}
    error_rect = Image.new('RGB', (8, 1), check_ng_color)
    for y in range(img.size[1]):
        for x in range(img.size[0]):
            xx: int = int(x / 8)
            if x % 8 == 0:
                all_8x_colors = {}
            color = img.getpixel((x, y))
            if color in all_colors:
                all_colors[color] += 1
            else:
                all_colors[color] = 1
            if color in all_8x_colors:
                all_8x_colors[color] += 1
            else:
                all_8x_colors[color] = 1
            if x % 8 == 7:
                is_ok = len(all_8x_colors.keys()) < 3
                if not is_ok:
                    # print(xx*8, y, is_ok)
                    output_img.paste(error_rect, (xx*8, y))
    return all_colors.keys()


def main() -> None:
    parser = argparse.ArgumentParser(
        description='横8ドット内に3色を使っていないか、画面全体に16色以上使っていないかを確認し、'
                    '問題がある部分をカラー表示した画像を出力する'
    )
    parser.add_argument('input', type=str, help='Input image')
    parser.add_argument('-o', '--output', type=str, help='Output image', default="")
    parser.add_argument('-m', '--merge_result_on_input_image', action="store_true",
                        help='チェック結果を元画像の上に重ねて表示する')
    parser.add_argument('-c','--check_ng_color', type=str, default='FF00FF',
                        help='チェックNGの色を16進数で指定する ex)FF00FF')
    args = parser.parse_args()

    img = Image.open(args.input)
    img = img.convert('RGBA')
    if len(args.check_ng_color) != 6:
        raise Exception("check_ng_color must be 6 hex digits")
    check_ng_color = tuple(int(args.check_ng_color[i:i + 2], 16) for i in (0, 2, 4))
    check_ng_color = (check_ng_color[0], check_ng_color[1], check_ng_color[2], 10)
    output_img = Image.new('RGBA', img.size, (0, 0, 0, 0))
    all_colors: list = check(img, output_img, check_ng_color)
    if len(all_colors) > 16:
        print(f'NG: {len(all_colors)} colors')
        for index, color in enumerate(all_colors):
            print(f'#{index:02d}: {color}')
    else:
        print(f'OK: {len(all_colors)} colors')
    if args.merge_result_on_input_image:
        ieb = ImageEnhance.Brightness(img)
        img = ieb.enhance(0.5)
        output_img = Image.alpha_composite(img, output_img)
    if args.output == '':
        output_img.resize((img.size[0] * 4, img.size[1] * 4), resample=Image.Resampling.NEAREST).show()
    elif Path(args.output).suffix == ".jpg" or Path(args.output).suffix == ".gif":
        output_img = img.convert('RGB')
        output_img.save(args.output)
    else:
        output_img.save(args.output)


if __name__ == "__main__":
    main()

以下はエラーのあるばあいの出力画像例とログ例。

NG: 17 colors
#00: (0, 0, 0, 255)
#01: (204, 195, 94, 255)
#02: (58, 162, 65, 255)
#03: (185, 94, 81, 255)
#04: (59, 165, 66, 255)
#05: (116, 208, 125, 255)
#06: (204, 204, 204, 255)
#07: (100, 220, 239, 255)
#08: (255, 255, 255, 255)
#09: (219, 101, 89, 255)
#10: (89, 85, 224, 255)
#11: (255, 137, 125, 255)
#12: (183, 102, 181, 255)
#13: (222, 208, 135, 255)
#14: (128, 118, 241, 255)
#15: (254, 254, 254, 255)
#16: (20, 20, 20, 255)
Previous post MSX風YS3OP:AfterEffects作例
Next post Blender 選択したオブジェクトすべてにラティス設定をしてゆがませる