見出し画像

12-5 画像ファイルを作って出力

同人誌について

 この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。

 同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。

(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)


説明と全体コード

 「example_command/gen_image_map.py」の説明です。『Pygame』の`Surface`に、マップの画像を描いたあと、PNGファイルを出力するプログラムです。

 ルートのディレクトリで、次のコマンドを実行すると、マップを生成して出力します。

.\.venv\Scripts\activate
cd .\example_command\
python -B gen_image_map.py

 ` -B`は`__pycache__`ディレクトリを作らないオプションです。

出力したmap.png

全体コード

 「example_command/gen_image_map.py」です。

# 同人誌の表紙用に、土地を配置したマップ画像を生成して出力する。
# ルートのディレクトリで、下のコマンドを順に実行する。
# 
# .\.venv\Scripts\activate
# cd .\example_command\
# python -B gen_image_map.py
#
# <root>/example_command/map.png が出力される。

import pygame, io, sys, os

# モジュール読み込みディレクトリの追加
p = os.path.abspath(os.path.join(os.path.dirname(__file__), '../src/'))
sys.path.append(p)

from mymod import data
from mymod import image

# Pygame開始
pygame.init()
pygame.display.set_mode((0, 0))

# CWDの変更
app_dir = os.path.dirname(os.path.dirname(__file__))    # 親の親
os.chdir(app_dir)

# 画像の読み込み
u = data.app.U
images = image.util.load_chip(data.app.IMAGE_LAND, False) # 画像読み込み

# マップの初期化
map_w = 30
map_h = 40
map = data.map.Map.from_wh(map_w, map_h)
map.gen(10, 10)

# Surfaceの作成と描画
surface = pygame.Surface((map_w * u, map_h * u))
for y in range(map_h):
    for x in range(map_w):
        pos = x + y * map_w
        land = map.map[pos]
        draw_x = x * u
        draw_y = y * u
        image_one = images[land]
        surface.blit(image_one, (draw_x, draw_y))

# 出力
buf = io.BytesIO()
pygame.image.save(surface, buf, "PNG")
p = os.path.abspath(os.path.join(os.path.dirname(__file__), 'map.png'))
with open(p, 'wb') as f:
    f.write(buf.getvalue())

# Pygame終了
pygame.quit()

インポート部分

 プログラムを示します。まずは、インポート部分です。

import pygame, io, sys, os

# モジュール読み込みディレクトリの追加
p = os.path.abspath(os.path.join(os.path.dirname(__file__), '../src/'))
sys.path.append(p)

from mymod import data
from mymod import image

 `pygame`と、標準ライブラリの`io` `sys` `os`を読み込みます。

 他のプロジェクトのモジュールを読み込むために、`sys.path`にパス`../src/`を追加します。このように設定しないと、『Python』のモジュールの仕組みでは、ルートをまたいだファイルの読み込みは基本的にできません。

 他のプロジェクトの`data` `image`モジュールを読み込みます。

準備と画像の読み込み

 次は、『Pygame』の開始と、画像を読み込むためのCWDの変更、画像の読み込みです。

# Pygame開始
pygame.init()
pygame.display.set_mode((0, 0))

# CWDの変更
app_dir = os.path.dirname(os.path.dirname(__file__))    # 親の親
os.chdir(app_dir)

# 画像の読み込み
u = data.app.U
images = image.util.load_chip(data.app.IMAGE_LAND, False) # 画像読み込み

マップの描画

 マップを初期化して、`Surface`を作成して描画します。

# マップの初期化
map_w = 30
map_h = 40
map = data.map.Map.from_wh(map_w, map_h)
map.gen(10, 10)

# Surfaceの作成と描画
surface = pygame.Surface((map_w * u, map_h * u))
for y in range(map_h):
    for x in range(map_w):
        pos = x + y * map_w
        land = map.map[pos]
        draw_x = x * u
        draw_y = y * u
        image_one = images[land]
        surface.blit(image_one, (draw_x, draw_y))

ファイルに出力

 最後にファイルに出力して、『Pygame』を終了します。

# 出力
buf = io.BytesIO()
pygame.image.save(surface, buf, "PNG")
p = os.path.abspath(os.path.join(os.path.dirname(__file__), 'map.png'))
with open(p, 'wb') as f:
    f.write(buf.getvalue())

# Pygame終了
pygame.quit()

 `io.BytesIO()`関数で書き込み用のバッファを作ります。そして、`pygame.image.save()`関数で、このバッファにPNG形式で画像を書き出します。

 そのあと`buf.getvalue()`関数でバイナリーを取り出して、ファイルに書き込みます。

 このように画像を生成して出力する方法を知っていれば、スクリーンショットを撮ったり、広報用の画像を作ったりできます。


同人誌について

 この連載は、同人誌『PythonとPygameで作る レトロ風RPG 全コード』を一部抜粋して編集したものです。

 同人誌本編には、ゲーム本体のソースコードや、各種のサンプルコード、Windowsで実行できるEXEファイルが付属しています。PDFで290ページの本になります。ぜひ、こちらもご購入ください。

(2024-03-28:ver1.0.4 に更新、2024-03-10:ver1.0.3 に更新)

 このnoteの記事と、Webページに一部抜粋版を掲載しています。

 技術系同人誌など まとめページ


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