Tkinter (Canvas)の内容をPILでキャプチャ

[pukiwiki]
Python標準のGUIライブラリ Tkinter。
グラフなどを描くためのCanvasウィジェットのポインタを渡すと、PngやJpeg、GIFなどの画像データとして画面をキャプチャ保存するコードを書いてみました。

キャプチャしたサンプル画像
[[http://boxheadroom.com/wp/wp-content/uploads/2009/05/rainbow-150×150.png:http://boxheadroom.com/wp/wp-content/uploads/2009/05/rainbow.png]]
あとでヘッダにしようかと。
[/pukiwiki]

[pukiwiki]
-Canvasウィジェットの座標を取得
-PILで、その場所のスクリーンキャプチャを取得

という回りくどいことをしています。普通の人は必要ないかと。

ファイル名 ”tkgrab.py”っとして保存してください
[/pukiwiki]

<<少しバグを修正>>

import Image,ImageGrab,ImageTk
import time
"""tkgrab.py
capture tkCanvas as PIL Image
"""

def grab(canvas,bbox=None):
    wx,wy=canvas.winfo_rootx(),canvas.winfo_rooty()
    inner_w,inner_h=int(canvas.cget("width")),int(canvas.cget("height"))
    outer_w,outer_h=canvas.winfo_width(),canvas.winfo_height()
    ox,oy=(outer_w-inner_w)//2,(outer_h-inner_h)//2
    #ox,oy=0,0
    if bbox :
        x0,y0,x1,y1=bbox
    else :
        x0,y0=0,0
        x1,y1=inner_w,inner_h

    im=ImageGrab.grab((wx+x0+ox,wy+y0+oy,wx+x1+ox,wy+y1+oy))
    return im    

def init(root):
    root.update()
    root.lift()



サンプル画像を描いて、キャプチャするためのテストプログラム。

<<修正>> tkgrabモジュールをインポートするのを忘れてたので追加

import Image,ImageGrab,ImageTk
import time
from tkgrab import init,grab
#上記 tkgrab.pyの最後に追加する場合は、
#この一行を削除。

if __name__=="__main__":
    import Tkinter as tk
    import colorsys
    W,H=760,200
    root=tk.Tk()

    cv=tk.Canvas(root,width=W,height=H,offset=tk.NW,bg="white")
    cv.xview("moveto",0)
    cv.yview("moveto",0)
    cv.pack()
    ox,oy=W//2,H//2
    from math import pi,sin,cos
    dt=4
    dx=W/360.
    for j in xrange(5) :
        h=j/5.
        col="#%02x%02x%02x"%colorsys.hsv_to_rgb(h,0.3,255)
        ox=-j*16
        pos=[]
        for i in xrange(0,360*2,dt):
            deg=pi*i/180.
            x=W*i/360.+ox
            y=-.7*H/2.*sin(deg)+H//2
            #print x,

            pos+=[x,y]
        cv.create_line(*pos , **dict(fill=col,width=2,smooth=True))
        #print
    #cv.create_rectangle(80,60,240-1,180-1)
    root.update()

    init(root)
    grab(cv).save("test1.png")
    box=[80,10,80+320-1,10+140-1]
    cv.create_rectangle(*box)
    root.update()
    box[2]+=1
    box[3]+=1
    grab(cv,box).save("test2.png")

Canvasには描画内容をpostscriptデータとして保存する 、postscriptメソッドがありますので、そちらを利用するのもよいかも。

コメントを残す

メールアドレスが公開されることはありません。