【问题标题】:python tkinter: how to work with pixels?python tkinter:如何使用像素?
【发布时间】:2012-08-30 08:13:14
【问题描述】:

使用谷歌(和这个网站)我看到了一些类似的问题,但我的问题仍然存在:

“我想画一个图像(不读取文件),能够操纵该图像中每个像素的颜色。”

我看到了另一个问题,建议在哪里做这样的事情:

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 建议的方法的方法,在链接的页面中有说明:

Why is Photoimage put slow?

【问题讨论】:

  • "...不使用任何第三方模块。"为什么? Tkinter 的画布不是为逐像素管理而设计的。
  • 好的,如果画布不允许快速执行此操作,我应该使用其他什么 tkinter 小部件来执行此操作?附言我修改了问题
  • Tkinter 没有什么可以快速做你想做的事。所以我再次问,为什么没有第三方模块?这似乎是不必要的限制。
  • 好的,你可以链接我一些非官方模块 - 但它们必须是跨平台的
  • 我在图像处理方面几乎没有经验,但主要的候选人似乎是 PIL、ImageMagic、Pycairo 和 scipy.ndimage 的 python 绑定。我知道 PIL 可以在 Windows、Mac 和 Linux 上运行,并且与 Tkinter 配合得很好。

标签: python image tkinter pixel


【解决方案1】:

确实很棘手—— 我以为您必须使用 Canvas 小部件,但这也无法访问 Pixels。 不过,嵌入在画布中的图像项目确实有。 Tkinter.PhotoImage 类 确实有一个“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 更好的图元。

【讨论】:

  • 好吧——如果合适的话,你总是可以接受答案。如果您反对创建 Gane,我建议使用预制图像,并根据 stackoverflow.com/questions/12250117/… 在 Tkinter 画布上移动图像
  • 我知道。您不能将常规 cPython 用于需要逐像素访问图像的视频游戏。仍然......实际上很少有视频游戏风格需要它 - 它们是通过使用低级库渲染 3d 对象/场景来完成的 - 在这种情况下,可以使用 python 来定位场景中的所有对象并调用渲染函数,或者只是重绘视图移动 2D 形状 - 这也可以使用 Python。不过,使用 Pypy,您可以比常规 Python 实现大约 10 倍的改进——我只是不知道哪些多媒体库将可用。
  • 十年后说“来自 Tkinter”需要小写(也感谢您的回答)
  • 好吧,十年前它通常是大写的。这就是从 Python2 到 Python3 的变化
【解决方案2】:

不要忘记在 canvas.create_image 之后保存参考。在某些情况下,尤其是在使用 PIL 模块时,python 会垃圾收集图像,即使它正在显示! 语法类似于 canvas.create_image((WIDTH/2, HEIGHT/2), image=img) canvas.image = img

【讨论】:

    猜你喜欢
    • 2018-09-29
    • 1970-01-01
    • 2015-06-04
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    • 2015-02-08
    • 2023-03-09
    • 2012-12-01
    相关资源
    最近更新 更多