“复制粘贴”Python程序

问题描述 投票:0回答:2

我目前正在尝试编写一个程序,该程序读取 GIF 文件,在屏幕上显示其图像,然后允许用户选择图像的矩形部分进行“复制和粘贴”,又称复制图像矩形,然后将结果保存为新的 GIF 文件。我已经做得很远了,但每次我以为我已经弄清楚了,似乎就会弹出一个新的错误!

# 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()
python image canvas tkinter gif
2个回答
0
投票

您的代码的主要问题是您为每个像素创建一个新的

PhotoImage
!相反,创建
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')

此外,

tuple(map(int, value.split(" ")))
函数中的
getRGB
行是错误的,因为
value
已经是您要创建的元组,而不是字符串。1)如您所见,我只是“内联”了该部分直接进入
box
函数。另一个问题是,您将复制的像素写入
x
y
,但您必须将它们写入
x-x1
y-y1

更新1:1)似乎

PhotoImage.get
的返回值取决于您使用的Python/Tkinter版本。在某些版本中,它返回一个元组,如
(41, 68, 151)
,而在其他版本中,它返回一个字符串,如
u'41 68 151'

更新2:正如@Oblivion所指出的,实际上您可以使用

from_coords
PhotoImage.write
参数来指定要保存到文件的图片区域。这样,
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])

-1
投票
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):
    x1, y1 = (event.x - 1), (event.y - 1)
    x2, y2 = (event.x + 1), (event.y + 1)
    canvas.create_rectangle(x1, y1, x2, y2)
    new_photo = copy_photo(photo, x1, y1, x2, y2)
    new_photo.write('new_image.gif', format='gif')

def copy_photo(photo, x1, y1, x2, y2):
    new_photo = PhotoImage(width=photo.width(), height=photo.height())
    for x in range(photo.width()):
        for y in range(photo.height()):
            if x1 <= x < x2 and y1 <= y < y2:
                r,g,b = getRGB(photo, x, y)
                new_photo.put("#%02x%02x%02x" % (r,g,b), (x,y))
            else:
                new_photo.put(photo.get(x, y), (x,y))
    return new_photo

def getRGB(photo, x, y):
    value = photo.get(x, y)
    return tuple(map(int, value.split(" ")))

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)

enter code here

canvas.mainloop()
© www.soinside.com 2019 - 2024. All rights reserved.