Python tkinter: как работать с пикселями? - программирование

Python tkinter: как работать с пикселями?

используя 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 помещается медленнее?

4b9b3361

Ответ 1

Это действительно сложно - Я думал, вам нужно использовать виджет Canvas, но у него также нет доступа к пикселам. Однако элементы изображения, встроенные в холст, имеют. Класс Tkinter.PhotoImage имеет метод "put", который принимает цвет в синтаксисе html/css и пиксельных координатах:

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, однако плохо документирована это Каир - он должен был иметь намного лучшие примитивы, чем Tkinter Canvas или PhotoImage.

Ответ 2

Не забудьте сохранить ссылку после canvas.create_image. В некоторых случаях, особенно при работе с модулем PIL, python будет мусорно-собирать изображение, даже если оно отображается! Синтаксис - это что-то вроде canvas.create_image((WIDTH/2, HEIGHT/2), image=img) canvas.image = img