PythonからWindowsのクリップボードに画像をコピーする
PythonのPillowモジュールのイメージオブジェクトを、Windows10のクリップボードにビットマップ画像としてコピーします。
目次
Python for windows extensions
Pillowやtkinterにクリップボードへのアクセスの方法があるようなのですが、画像をクリップボードからダウンロードする方法はドキュメントを見ても見つかりませんでした。
そこで、 Pywin32(Python for windows extensions) を使ってクリップボードにアクセスします。
GitHubのreadmeにはpipでのインストールはexperimental(Release 224時点)と書かれていたので、 ダウンロードサイト から適当なものをダウンロードしてインストールしました。
Pywin32をインストールすると、win32clipboardというモジュールを使えるようになります。このモジュールに含まれているメソッドを使って
クリップボードを開く。
クリップボードをクリアする。
クリップボードにデータをセットする。
クリップボードを閉じる。
ということをします。
データをセットするメソッドはこのようなものです。詳しくは マニュアル を参照してください。
ret = win32clipboard.SetClipboardData(format, hMem )
変数 |
型 |
内容 |
---|---|---|
format |
クリップボードにセットするデータの書式。 |
|
hMem |
int/buffer |
セットするデータ。 |
ret |
int |
データのハンドル。 |
画像をコピーする場合は、formatはCF_DIBのようです。
Pillow ImageオブジェクトをWindows bitmapに変換する
PillowのImageオブジェクトをそのままセットしようとすると(たぶん)エラーになります。ndarrayですからね。
ところが、PillowにはBitmapオブジェクトに変換するコマンドが見当たりません。
そこで、メモリストリームにbitmap形式で出力して、そのメモリストリーム上のデータを読み込んでから、SetClipboardDataメソッドに渡すことにします。
こんな感じですね。
import io
from PIL import Image
output = io.BytesIO()
image.convert('RGB').save(output, 'BMP')
data = output.getvalue()[14:]
output.close()
オープンしたものはクローズすることを忘れずに。
クリップボードへ画像をコピーする例
プロ生ちゃん の画像をtkinterで表示して、クリップボードにコピーして、ペイントにペーストしてみました。
クリップボードにデータをセットする側のコードはこんな感じです。
import tkinter
import tkinter.ttk
from PIL import Image, ImageTk
import win32clipboard
import io
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.original_button = tkinter.ttk.Button(self, text='Copy to Clipboard')
self.original_button.grid(row=0, column=1)
self.original_button.bind('<Button-1>', copy_to_clipboard)
# canvas
self.test_canvas = tkinter.Canvas(self, width=original_image.width, height=original_image.height)
self.test_canvas.grid(row=0, column=0)
# canvasに初期画像を表示
self.test_canvas.photo = ImageTk.PhotoImage(original_image)
self.image_on_canvas = self.test_canvas.create_image(0, 0, anchor='nw', image=self.test_canvas.photo)
def copy_to_clipboard(event):
# メモリストリームにBMP形式で保存してから読み出す
output = io.BytesIO()
original_image.convert('RGB').save(output, 'BMP')
data = output.getvalue()[14:]
output.close()
send_to_clipboard(win32clipboard.CF_DIB, data)
def send_to_clipboard(clip_type, data):
# クリップボードをクリアして、データをセットする
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardData(clip_type, data)
win32clipboard.CloseClipboard()
# 画像ファイル読み込み
original_image = Image.open('test_figure.png')
# アプリケーション起動
root = tkinter.Tk()
app = Application(master=root)
app.mainloop()
copy_to_clipboardという関数で、PillowのImageオブジェクトからビットマップへ変換します。
send_to_clipboardという関数で、データをクリップボードにセットします。
動かしてみるとこんな感じです。
公開日
広告
PythonでGUIカテゴリの投稿
- PythonからWindowsのクリップボードに画像をコピーする
- PythonでCanvasをリサイズできるようにしてみた
- PythonでGUIに画像を表示する
- Pythonでクリップボードとのデータのやりとりをする
- Pythonでグラフ(Matplotlib)を表示して動的に変更する
- Pythonでディレクトリを選択するダイアログを使う
- Pythonでファイルを開くダイアログを使う
- Pythonで名前を付けて保存するダイアログを使う
- PythonのGUIを試してみた
- Pythonのcanvasにマウスで線を描いてみる
- Pythonのcanvasに表示した四角形を変形する
- Pythonのcanvasのマウスポインタの座標を取得する
- Pythonのtkinterのcanvasにクリップボードから画像をペーストする
- Pythonのtkinterのcanvasに表示する画像を切り替える