Pythonのtkinterのcanvasにクリップボードから画像をペーストする

PythonでPillowを使ってクリップボードから画像データを取得します。そして、取得したデータをtkinterのcanvasに貼り付けます。

目次

  1. クリップボードから画像を取得
  2. 試してみた

クリップボードから画像を取得

クリップボードに画像を送る際には win32clipboardを使いました が、クリップボードからの画像取得にはPillowを使います。いずれ、取得した画像を加工しますからね。

Pillowでクリップボードからデータを取得するには、ImageGrabモジュールのgrabclipboardメソッドを使用します。

im = PIL.ImageGrab.grabclipboard()

クリップボードに画像が格納されていた場合は、戻り値がPillowのイメージクラスのオブジェクトになります。クリップボードが画像以外の場合は、Noneかリストが返ってきます。

戻り値の型がいくつかあるので、isinstance関数で戻り値のクラスの判定をします。戻り値のオブジェクトのクラスがImage.Image(Pillowのイメージオブジェクト)かその派生クラスの場合だけ、画像が取得できた場合の処理をするわけです。

試してみた

プロ生ちゃん の画像をペイントで開いて、クリップボード経由で取得してみます。

import tkinter
import tkinter.ttk
from PIL import Image, ImageTk, ImageGrab

class Application(tkinter.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.master.title('clipboard trial')
        self.pack()
        self.create_widgets()

    def create_widgets(self):
        # ボタン
        self.test_button = tkinter.ttk.Button(self, text='Paste from Clipboard')
        self.test_button.grid(row=0, column=1)
        self.test_button.bind('<Button-1>', paste_from_clipboard)

        # ラベル
        self.variable_str = tkinter.StringVar()
        self.test_label = tkinter.ttk.Label(self, textvariable=self.variable_str)
        self.test_label.grid(row=1, column=1)

        # canvas
        self.test_canvas = tkinter.Canvas(self, width=300, height=300, highlightthickness=0)
        self.test_canvas.grid(row=0, column=0, rowspan=2)

def paste_from_clipboard(event):
    # クリップボードからデータ取得
    im = ImageGrab.grabclipboard()
    if isinstance(im, Image.Image):
        app.test_canvas.config(width=im.width, height=im.height, )
        app.test_canvas.photo = ImageTk.PhotoImage(im)
        app.image_on_canvas = app.test_canvas.create_image(0, 0, anchor='nw', image=app.test_canvas.photo)
        app.variable_str.set('Pasted.')
    else:
        app.variable_str.set('Not image.')

# アプリケーション起動
root = tkinter.Tk()
app = Application(master=root)
app.mainloop()

ボタンをクリックするとpaste_from_clipboard関数が呼び出されます。

するとクリップボードからデータを取得して、そのデータのクラスを確認して、画像データならcanvasのサイズを変更した上で描画します。画像データでなければ、ラベルにNot imageと表示します。

実際に動かしてみるとこんな感じです。

広告

PythonでGUIカテゴリの投稿