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)







