[英]"copy and paste" python program
I'm currently trying to write a program that reads a GIF file, displays its image on the screen, then allows the user to select a rectangular portion of the image to "copy and paste", AKA to then copy the image within the rectangle and then save the result as a new GIF file.我目前正在尝试编写一个程序来读取 GIF 文件,在屏幕上显示其图像,然后允许用户选择图像的矩形部分进行“复制和粘贴”,也就是在矩形内复制图像然后将结果另存为新的 GIF 文件。 I've gotten pretty far with it, but every time I think I've figured it out is seems that a new error pops up!
我已经走得很远了,但是每次我想我已经弄清楚时,似乎都会弹出一个新错误!
# CopyAndPaste.py
# This program is designed to read a GIF file, display its image on the screen, allows the user to
# select a rectangular portion of the image to copy and paste, and then save the result as a new GIF file
import tkinter
from tkinter import *
import base64
root = Tk()
def action(canvas):
canvas.bind("<Button-1>", xaxis)
canvas.bind("<ButtonRelease-1>", yaxis)
canvas.bind("<ButtonRelease-1>", box)
def xaxis(event):
global x1, y1
x1, y1 = (event.x - 1), (event.y - 1)
print (x1, y1)
def yaxis(event):
global x2, y2
x2, y2 = (event.x + 1), (event.y + 1)
print (x2, y2)
def box(event):
photo = PhotoImage(file="picture.gif")
yaxis(event)
canvas.create_rectangle(x1,y1,x2,y2)
for x in range(x1, x2):
for y in range(y1, y2):
r,g,b = getRGB(photo, x, y)
newImage(r, g, b, x, y)
def getRGB(photo, x, y):
value = photo.get(x, y)
return tuple(map(int, value.split(" ")))
def newImage(r, g, b, x, y):
picture = PhotoImage(width=x, height=y)
picture.put("#%02x%02x%02x" % (r,g,b), (x,y))
picture.write('new_image.gif', format='gif')
canvas = Canvas(width=500, height=250)
canvas.pack(expand=YES, fill=BOTH)
photo = PhotoImage(file="picture.gif")
canvas.create_image(0, 0, image=photo, anchor=NW)
canvas.config(cursor='cross')
action(canvas)
root.mainloop()
The main problem with your code is that you create a new PhotoImage
for each pixel!您的代码的主要问题是您为每个像素创建了一个新的
PhotoImage
! Instead, create the PhotoImage
once and just add the pixels in the double- for
-loop.相反,只需创建一次
PhotoImage
并在双for
循环中添加像素。
def box(event):
yaxis(event)
canvas.create_rectangle(x1, y1, x2, y2)
picture = PhotoImage(width=(x2-x1), height=(y2-y1))
for x in range(x1, x2):
for y in range(y1, y2):
r, g, b = photo.get(x, y)
picture.put("#%02x%02x%02x" % (r, g, b), (x-x1, y-y1))
picture.write('new_image.gif', format='gif')
Also, the line tuple(map(int, value.split(" ")))
in your getRGB
function is wrong, as value
is already the tuple you want to create, not a string.此外,您的
getRGB
函数中的tuple(map(int, value.split(" ")))
行是错误的,因为value
已经是您要创建的元组,而不是字符串。 1) As you can see, I just 'inlined' that part directly into the box
function. 1)如您所见,我只是将该部分直接“内联”到
box
函数中。 Another problem was that you wrote the copied pixels to x
and y
, but you have to write them to x-x1
and y-y1
instead.另一个问题是您将复制的像素写入
x
和y
,但您必须将它们写入x-x1
和y-y1
。
Update 1: 1) It seems like the return value of PhotoImage.get
depends on the version of Python/Tkinter you are using.更新 1: 1)看起来
PhotoImage.get
的返回值取决于您使用的 Python/Tkinter 版本。 In some versions, it returns a tuple, like (41, 68, 151)
, and in others, a string, like u'41 68 151'
.在某些版本中,它返回一个元组,例如
(41, 68, 151)
,而在其他版本中,它返回一个字符串,例如u'41 68 151'
。
Update 2: As pointed out by @Oblivion, you can in fact just use the from_coords
parameter of PhotoImage.write
to specify the region of the picture to be saved to file.更新 2:正如@Oblivion 所指出的,您实际上可以只使用
PhotoImage.write
的from_coords
参数来指定要保存到文件的图片区域。 With this, the box
function can be simplified as有了这个,
box
函数可以简化为
def box(event):
yaxis(event)
canvas.create_rectangle(x1, y1, x2, y2)
photo.write('new_image.gif', format='gif', from_coords=[x1, y1, x2, y2])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.