20

Google(およびこのサイト)を使用して、同様の質問をいくつか見ましたが、私の問題はまだここにあります:

「(ファイルを読み取らずに) 画像を描画し、その画像内のすべてのピクセルの色を操作できるようにしたい。」

私はこのようなことをするように提案された別の質問を見ました:

from tkinter import *
A=Tk()
B=Canvas(A)
B.place(x=0,y=0,height=256,width=256)
for a in range(256):
    for b in range(256):
        B.create_line(a,b,a+1,b+1,fill=pyList[a][b])#where pyList is a matrix of hexadecimal strings
A.geometry("256x256")
mainloop()

実際、これは私の質問に答えますが...非常に遅いです。1920x1080 の画像はどうすればよいですか? 私の死を待つ?

だから私は何かを上記のコードと同じように実行するように求めていますが、より高速な方法で

私は jsbueno によって提案された方法を改善する方法を見つけました、それはリンクされたページで説明されています:

Photoimage が遅いのはなぜですか?

4

2 に答える 2

37

確かに注意が必要です。Canvasウィジェットを使用する必要があると思いましたが、Pixelsにもアクセスできません。ただし、Canvasに埋め込まれた画像アイテムにはあります。Tkinter.PhotoImageクラスには、16進形式の色とピクセル座標を受け入れる「put」メソッドがあります。

from tkinter import Tk, Canvas, PhotoImage, mainloop
from math import sin

WIDTH, HEIGHT = 640, 480

window = Tk()
canvas = Canvas(window, width=WIDTH, height=HEIGHT, bg="#000000")
canvas.pack()
img = PhotoImage(width=WIDTH, height=HEIGHT)
canvas.create_image((WIDTH/2, HEIGHT/2), image=img, state="normal")

for x in range(4 * WIDTH):
    y = int(HEIGHT/2 + HEIGHT/4 * sin(x/80.0))
    img.put("#ffffff", (x//4,y))

mainloop()

良いニュースは、このように行われたとしても、更新は「ライブ」であるということです。画像にピクセルを設定すると、それらが画面に表示されます。


これは、画面上に高レベルの線を描画する方法よりもはるかに高速であるはずですが、多くのピクセルでは、すべてのピクセルにPython関数呼び出しが必要なため、それでも低速になります。ピクセルを直接操作する他の純粋なPythonの方法は、この問題に悩まされます。唯一の方法は、Pythonコードからネイティブコードで一度に複数のピクセルを操作するプリミティブを呼び出すことです。

2D描画を取得するための優れたクロスプラットフォームライブラリですが、文書化が不十分なCairoもあります。これは、TkinterのCanvasやPhotoImageよりもはるかに優れたプリミティブを備えているはずです。

于 2012-09-05T17:54:41.167 に答える
5

canvas.create_image の後に参照を保存することを忘れないでください。場合によっては、特に PIL モジュールを使用している場合、python は画像が表示されているにもかかわらず、画像をガベージ コレクションします! 構文は次のようなものです canvas.create_image((WIDTH/2, HEIGHT/2), image=img) canvas.image = img

于 2016-12-25T10:01:12.160 に答える