python tkinter: how to work with pixels?

风流意气都作罢 提交于 2019-11-27 13:56:51

问题


using google (and this site) i have seen some similar questions but my problem is still here:

"i want to draw an image (without reading a file) , being able to manipulate every single pixel's colour in that image."

i have seen another question where was suggested to do something like this:

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()

in fact this answers my question but... it is extremely slow. what should i do with a 1920x1080 image ? wait for my death?

so i am asking something to perform the same as the above code but in a faster way

i have found a way to improve the method suggested by jsbueno , it is explained in the page linked :

Why is Photoimage put slow?


回答1:


It is indeed tricky -- I thought you had to use a Canvas widget, but that has no access to Pixels either. Image items embedded in the Canvas do have, though. The Tkinter.PhotoImage class does have a "put" method that accepts a color in hex format and pixel coordinates:

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()

The good news is that even it being done this way, the updates are "live": you set pixels on the image, and see them showing up on screen.


This should be much faster than the way drawing higher level lines on screen - but for lots of pixels it still will be slow, due to a Python function call needed for every pixel. Any other pure python way of manipulating pixels directly will suffer from that - the only way out is calling primitives that manipulate several pixels at a time in native code from your Python code.

A nice cross-platform library for getting 2d drawing, however poorly documented as well is Cairo - it would should have much better primitives than Tkinter's Canvas or PhotoImage.




回答2:


Don't forget to save a reference after canvas.create_image. In some cases, especially when working with the PIL module, python will garbage-collect the image, even though it is being displayed! Syntax is something like canvas.create_image((WIDTH/2, HEIGHT/2), image=img) canvas.image = img



来源:https://stackoverflow.com/questions/12284311/python-tkinter-how-to-work-with-pixels

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!