使用 PIL 的 ImageDraw 模块
我正在尝试使用 PIL 的 ImageDraw 模块进行单独的像素操作。下面的代码应该创建 Tkinter 画布小部件。然后打开一张图像,将一个像素的颜色更改为红色,然后将图像嵌入到画布小部件中。但是,它似乎不起作用。
我的代码:
import Tkinter
from PIL import ImageTk, Image, ImageDraw
class image_manip(Tkinter.Tk):
def __init__(self):
Tkinter.Tk.__init__(self)
self.configure(bg='red')
self.ImbImage = Tkinter.Canvas(self, highlightthickness=0, bd=0, bg='blue')
self.ImbImage.pack()
im = Image.open(r'C:\Python26\Suite\test.png')
print im.format, im.size, im.mode
im = ImageDraw.Draw(im)
im = im.point((0, 0), fill="red")
self.i = ImageTk.PhotoImage(im)
self.ImbImage.create_image(139, 59, image=self.i)
def run():
image_manip().mainloop()
if __name__ == "__main__":
run()
运行代码时出现以下错误:
Exception AttributeError: "PhotoImage instance has no attribute '_PhotoImage__photo'" in <bound method PhotoImage.__del__ of <PIL.ImageTk.PhotoImage instance at 0x05DF7698>> ignored
Traceback (most recent call last):
File "<string>", line 245, in run_nodebug
File "C:\Python26\Suite\test_image.py", line 30, in <module>
run()
File "C:\Python26\Suite\test_image.py", line 28, in run
image_manip().mainloop()
File "C:\Python26\Suite\test_image.py", line 20, in __init__
self.i = ImageTk.PhotoImage(im)
File "C:\Python26\lib\site-packages\PIL\ImageTk.py", line 109, in __init__
mode = Image.getmodebase(mode)
File "C:\Python26\lib\site-packages\PIL\Image.py", line 245, in getmodebase
return ImageMode.getmode(mode).basemode
File "C:\Python26\lib\site-packages\PIL\ImageMode.py", line 50, in getmode
return _modes[mode]
KeyError: None
I'm trying to do individual pixel manipulation using PIL's ImageDraw Module. The code bellow is supposed to create Tkinter canvas widget. Then open an image, change one pixel's color to red, then embed the image in the canvas widget. However, it doesn't seem to be working.
My Code:
import Tkinter
from PIL import ImageTk, Image, ImageDraw
class image_manip(Tkinter.Tk):
def __init__(self):
Tkinter.Tk.__init__(self)
self.configure(bg='red')
self.ImbImage = Tkinter.Canvas(self, highlightthickness=0, bd=0, bg='blue')
self.ImbImage.pack()
im = Image.open(r'C:\Python26\Suite\test.png')
print im.format, im.size, im.mode
im = ImageDraw.Draw(im)
im = im.point((0, 0), fill="red")
self.i = ImageTk.PhotoImage(im)
self.ImbImage.create_image(139, 59, image=self.i)
def run():
image_manip().mainloop()
if __name__ == "__main__":
run()
I get the following error upon running my code:
Exception AttributeError: "PhotoImage instance has no attribute '_PhotoImage__photo'" in <bound method PhotoImage.__del__ of <PIL.ImageTk.PhotoImage instance at 0x05DF7698>> ignored
Traceback (most recent call last):
File "<string>", line 245, in run_nodebug
File "C:\Python26\Suite\test_image.py", line 30, in <module>
run()
File "C:\Python26\Suite\test_image.py", line 28, in run
image_manip().mainloop()
File "C:\Python26\Suite\test_image.py", line 20, in __init__
self.i = ImageTk.PhotoImage(im)
File "C:\Python26\lib\site-packages\PIL\ImageTk.py", line 109, in __init__
mode = Image.getmodebase(mode)
File "C:\Python26\lib\site-packages\PIL\Image.py", line 245, in getmodebase
return ImageMode.getmode(mode).basemode
File "C:\Python26\lib\site-packages\PIL\ImageMode.py", line 50, in getmode
return _modes[mode]
KeyError: None
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的问题是您正在将
im
重新分配给多个事物。当您调用
ImageTk.PhotoImage(im)
时,该函数需要一个 PIL 图像对象,但您已将im
分配给point() 的结果
函数,实际上返回None
。这就是你的问题的原因。我认为您误解了 ImageDraw 的工作原理。请查看此处示例。基本上:
ImageDraw
的实例。ImageDraw
直接在图像上绘制您在构造期间给出了它ImageDraw
对象。它不包含任何重要信息,因为所有内容都直接写入图像。这是固定的
__init__
方法:您会注意到我修复了一些问题:
ImageDraw
实例分配给一个单独的变量draw.rectangle
的返回值 - 它实际上返回None
,就像大多数其他绘图函数一样。draw
变量create_image
时将图像置于画布的中心Your problem is you're reassigning
im
to multiple things.When you call
ImageTk.PhotoImage(im)
, the function expects a PIL image object, but you've already assignedim
to the result of thepoint()
function, which actually returnsNone
. This is the cause of your problem.I think you're misunderstanding how ImageDraw works. Have a look here for an example. Basically:
ImageDraw
if you want to draw something complicated on your PIL ImageImageDraw
paints directly on the image you've given it during construction timeImageDraw
object at any point. It doesn't contain any important information because everything is written directly to the image.Here's the fixed
__init__
method:You'll notice I've fixed a couple of things:
ImageDraw
instance to a separate variabledraw.rectangle
-- it actually returnsNone
, as most other drawing functions do.draw
variable after we're done drawingcreate_image