ITエンジニアが仕事に対して思うこと

ITエンジニアとして働く中で感じたことを、現場の温度感そのままに言語化するブログです。設計・実装・運用のリアル、学び続ける負荷、品質とスピードのせめぎ合い、コミュニケーションの難しさなど、きれいごとだけでは語れない「仕事の実態」を整理します。誰かを責めるのではなく、なぜそうなるのかを構造で捉え、明日から少し楽に、少し強く働ける視点を提供します。新人から中堅、マネジメントまで参考に。

Tkinterで保存した画像が真っ白に!?解決法を丁寧に解説!

みなさん、こんにちは!今日はちょっとした問題に直面している方も多いのではないでしょうか?そう、Tkinterで作成した画像を保存しようとしたら、真っ白になってしまうという現象です。この問題に遭遇したとき、かなり悩むかもしれませんが、今回はその原因と解決方法について、感情たっぷりに解説していきます!

「なぜ画像が白くなってしまうの?」と感じるその不安、わかりますよ!大事なプログラムが動かないとき、私たちはまるで「このプログラムに嫌われているのか?」と感じてしまいますよね。ですが、心配無用です!この記事を読み終える頃には、バッチリ画像が保存できるようになりますよ!

では、早速一緒に解決していきましょう!

問題の再現コード

まず、問題がどのように発生するかを再現してみましょう。下記のコードを実行して、Canvasに描いたものを画像として保存しようとしてみます。

import tkinter as tk
from PIL import Image, ImageDraw

def save_image():
    # 画像を保存しようとする
    image = Image.new("RGB", (200, 200), (255, 255, 255))
    draw = ImageDraw.Draw(image)
    draw.rectangle([50, 50, 150, 150], fill="blue")
    image.save("output.png")

root = tk.Tk()
canvas = tk.Canvas(root, width=200, height=200)
canvas.pack()

# 青い四角形を描画
canvas.create_rectangle(50, 50, 150, 150, fill="blue")

# ボタンで画像保存
button = tk.Button(root, text="保存", command=save_image)
button.pack()

root.mainloop()

このコードでは、TkinterのCanvasに青い四角形を描いています。そして、ボタンを押すとsave_image関数が実行されて、画像が保存される仕組みです。

でも、実際に保存してみると… output.pngは真っ白!

「え、何がいけないの?」と思うかもしれません。実はこの問題の原因は、TkinterのCanvasに描いた内容は直接保存されていないということなんです。TkinterのCanvasはあくまで画面に描画するもので、保存のためには別の工夫が必要です。

なぜCanvasの内容が保存されないのか?

TkinterのCanvasはウィンドウに直接描画しているため、その内容は単純に保存することができません。私たちが画像ファイルに保存したいときは、Pillowライブラリなどを使って、Canvasに描いたものを画像形式に変換して保存する必要があります。

つまり、TkinterのCanvasは「ウィンドウ」に表示されているだけで、そのままでは「画像データ」にはなっていないのです。

解決方法

この問題を解決するためには、Canvas上に描かれた内容をPillowライブラリを使って保存する必要があります。それでは、正しいコードを書いてみましょう!

import tkinter as tk
from PIL import Image, ImageDraw, ImageGrab

def save_canvas_as_image(canvas):
    # キャンバスの座標を取得
    x=root.winfo_rootx() + canvas.winfo_x()
    y=root.winfo_rooty() + canvas.winfo_y()
    x1=x + canvas.winfo_width()
    y1=y + canvas.winfo_height()
    
    # キャンバスの領域をキャプチャして画像として保存
    image = ImageGrab.grab().crop((x, y, x1, y1))
    image.save("canvas_output.png")

root = tk.Tk()
canvas = tk.Canvas(root, width=200, height=200)
canvas.pack()

# 青い四角形を描画
canvas.create_rectangle(50, 50, 150, 150, fill="blue")

# 保存ボタン
button = tk.Button(root, text="画像を保存", command=lambda: save_canvas_as_image(canvas))
button.pack()

root.mainloop()

解説

  1. ImageGrab を使って、画面の一部をキャプチャしています。winfo_rootx()winfo_rooty()でCanvasの座標を取得し、crop()を使ってCanvasの範囲を切り取っています。
  2. save_canvas_as_image 関数では、TkinterのCanvasの内容を画像として保存しています。

この方法であれば、Canvasに描かれたものがしっかりと画像ファイルとして保存されるようになります!

サンプルコードの実行結果

実際にこのコードを実行してみると、青い四角形が描かれた画像がcanvas_output.pngとして保存されます。これで、「真っ白な画像しか保存されない!」という悩みから解放されますね。

$ python save_canvas.py

実行後、以下のような青い四角形が描かれた画像が保存されます。

青い四角形が描かれた画像

これでやっと、思い通りに画像が保存できるようになりましたね!次回ももっと面白いトピックでお届けする予定なので、ぜひ引き続き学んでいきましょう。

最後に

いかがでしたでしょうか?Tkinterで作成したCanvasの内容を画像として保存する際に、真っ白な画像しか保存されないという問題、これで解決できましたね。プログラムのバグやトラブルに出会うたびに焦る気持ち、わかります。でも、それを解決するたびにスキルが磨かれていくんです。

次回は、Tkinterでボタン操作やウィンドウのデザインをもっと自由にカスタマイズする方法についてお話ししたいと思います。ぜひお楽しみに!

この記事が役に立ったと思っていただけたら、ぜひTwitterでフォローしてください!一緒に学んで、成長していきましょう!