棚上げしてあったPyGameのチュートリアルにチャレンジ開始。
ついでに、PyGameの画面を静止画や動画で保存できるようにするモジュールを書いてみました。
PyGameとは、ゲーム用のライブラリSDLをPythonから使えるようにしたもの。
- Pythonでゲーム作りますが何か?
やっと4分の1ぐらいサンプルコードを動かしました - Pygame入門
- Pygame公式
クラスライブラリを調べるのに。
本格的にゲームを作るつもりは無いのですが。。。ちょっとしたインタラクティブな映像を作るのによさげ。
表示中の映像をAVIに保存する機能は、標準では用意されてないみたいなので、書いてみました。
(もっと 賢いやり方があったら教えてください。。。)
数日~数週間、一時 勉強を中断しなきゃいけないので、コードを紛失しないようにメモ。
また、時間が出来たら 動くサンプルコード&サンプル動画を作成予定
<<注意>>
音声は保存できません。 (OpenCVの制限)
コード
以下を videowriter.pyというファイル名で保存。
- Python 2.5系で検証
- 必要なライブラリは PyGame, PIL, OpenCV (CVtypes)
- CVtypesについてはコチラ
#!/usr/bin/env python # -*- coding: utf-8 -*- #videowriter.py import Image import CVtypes as cv import atexit #SCREEN_SIZE = (W, H) class VideoWriter(object): def write_frame_pygame(self,sc): """ write_frame for PyGame Surface """ #print self.idx self.idx+=1 s=str(sc.get_buffer().raw) cv.cvSetData(self.cvimg,s,self.W*self.bpp) #cv.cvShowImage("test",self.cvimg) cv.cvWriteFrame(self.vw,self.cvimg) def atexist(self): cv.cvReleaseVideoWriter(self.vw) def __init__(self,fname, size=(640,480), fps=30,codec=-1,bpp=4,mode="pygame"): """ bpp=bit_per_pixel mode , now pygame only (extendable) """ self.idx=0 modelist={"pygame":self.write_frame_pygame} self.write_frame=modelist[mode] self.bpp=bpp self.SCREEN_SIZE=size self.W,self.H=size self.vw=cv.cvCreateVideoWriter(fname, codec,fps,cv.CvSize(*size)) self.cvimg=cv.cvCreateImage(cv.CvSize(*size),8,bpp) atexit.register(self.atexist) #終了時に aviファイルを自動的にclose #オマケ #PyGameのSurfaceデータを PIL画像データに変換 def img(s): #ピクセル取得 buf=s.get_buffer() im =Image.fromstring("RGBA",s.get_size(),buf.raw) B,G,R,A=im.split() return Image.merge("RGBA",(R,G,B,A))
使い方
このコード自体は検証してないです。 後日、ちゃんと動くサンプルを作成予定~
代表的なPyGameのサンプルコードは、こんな感じのループになってるのですが
import pygame from pygame.locals import * from videowriter import VideoWriter,img #☆☆☆ インポート # vw=VideoWriter("filename.avi") #☆☆☆ 出力ファイル名を指定して初期化 # SCREEN_SIZE=(640,480) pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE) ~~~~(中略)~~~~~~ clock = pygame.time.Clock() while True: #Pygameのメインループ clock.tick(30) #毎秒の表示コマ数に応じてウェイト #ディスク上のAVIへ書き込むことを考えると、FPSは 15コマ/秒程度がよさげ # (速いマシンなら もっと速くできるかもですが) screen.blit( ほげほげ, (x,y)) # 個々のキャラクターを描画 ~~~~このへんに、描画のメイン処理~~~~~~ pygame.display.update() #画面に反映 vw.write_frame(screen) #☆☆☆ ここでAVI に 1コマ書き出し for event in pygame.event.get(): #窓を閉じると終了 if event.type == QUIT: sys.exit()
という感じで使います。
オマケの静止画保存
from videowriter import VideoWriter,img #☆☆☆ インポート from datetime import datetime #画面のスクリーンショットをとりたくなった場所で適宜 im=img(screen) im.save("screenshot%s.jpg"%datetime.today().strftime("%Y%m%d-%H%M%S"))