
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__`ディレクトリを作らないオプションです。

全体コード
「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ページに一部抜粋版を掲載しています。
技術系同人誌など まとめページ