[英]Image Cropping using Python
I am new to Python coding and I am writing a program in which I will be cropping an entered image and then saving it in a location.我是 Python 编码的新手,我正在编写一个程序,我将在其中裁剪输入的图像,然后将其保存在某个位置。 Now, I am being able to do this using a combination of PIL and pygame.
现在,我可以使用 PIL 和 pygame 的组合来做到这一点。 But the problem is that, when I am selecting the image from the open pygame window, the selection area is totally opaque and I am not able to see through the region I am selecting.
但问题是,当我从打开的 pygame window 中选择图像时,选择区域完全不透明,我无法看穿我选择的区域。 This is causing problems for my boss who wants to be able to see through it as he selects.
这给我的老板带来了问题,他希望能够在他选择的时候看穿它。 For you guys to better understand the problem, I am writing my code here:
为了让你们更好地理解这个问题,我在这里写我的代码:
import pygame, sys
from PIL import Image
pygame.init()
def displayImage( screen, px, topleft):
screen.blit(px, px.get_rect())
if topleft:
pygame.draw.rect( screen, (128,128,128), pygame.Rect(topleft[0], topleft[1], pygame.mouse.get_pos()[0] - topleft[0], pygame.mouse.get_pos()[1] - topleft[1]))
pygame.display.flip()
def setup(path):
px = pygame.image.load(path)
screen = pygame.display.set_mode( px.get_rect()[2:] )
screen.blit(px, px.get_rect())
pygame.display.flip()
return screen, px
def mainLoop(screen, px):
topleft = None
bottomright = None
n=0
while n!=1:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP:
if not topleft:
topleft = event.pos
else:
bottomright = event.pos
n=1
displayImage(screen, px, topleft)
return ( topleft + bottomright )
if __name__ == "__main__":
input_loc="C:\pic1.PNG"
output_loc="C:\pic2.PNG"
screen, px = setup(input_loc)
left, upper, right, lower = mainLoop(screen, px)
im = Image.open(input_loc)
im = im.crop(( left, upper, right, lower))
pygame.display.quit()
im.save(output_loc)
Any help is appreciated.任何帮助表示赞赏。 Regards.
问候。
I took a quick look and fixed a few other problems along the way.我快速浏览了一下,并在此过程中解决了一些其他问题。 Essentially my changes do this:
基本上我的更改是这样做的:
Here is a screenshot of running the fixed code:这是运行固定代码的屏幕截图:
I split the code into two parts to avoid the scrollbars:我将代码分成两部分以避免滚动条:
import pygame, sys
from PIL import Image
pygame.init()
def displayImage(screen, px, topleft, prior):
# ensure that the rect always has positive width, height
x, y = topleft
width = pygame.mouse.get_pos()[0] - topleft[0]
height = pygame.mouse.get_pos()[1] - topleft[1]
if width < 0:
x += width
width = abs(width)
if height < 0:
y += height
height = abs(height)
# eliminate redundant drawing cycles (when mouse isn't moving)
current = x, y, width, height
if not (width and height):
return current
if current == prior:
return current
# draw transparent box and blit it onto canvas
screen.blit(px, px.get_rect())
im = pygame.Surface((width, height))
im.fill((128, 128, 128))
pygame.draw.rect(im, (32, 32, 32), im.get_rect(), 1)
im.set_alpha(128)
screen.blit(im, (x, y))
pygame.display.flip()
# return current box extents
return (x, y, width, height)
And part 2 (concatenate to the above):第 2 部分(与上述内容连接):
def setup(path):
px = pygame.image.load(path)
screen = pygame.display.set_mode( px.get_rect()[2:] )
screen.blit(px, px.get_rect())
pygame.display.flip()
return screen, px
def mainLoop(screen, px):
topleft = bottomright = prior = None
n=0
while n!=1:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP:
if not topleft:
topleft = event.pos
else:
bottomright = event.pos
n=1
if topleft:
prior = displayImage(screen, px, topleft, prior)
return ( topleft + bottomright )
if __name__ == "__main__":
input_loc = 'stack.png'
output_loc = 'out.png'
screen, px = setup(input_loc)
left, upper, right, lower = mainLoop(screen, px)
# ensure output rect always has positive width, height
if right < left:
left, right = right, left
if lower < upper:
lower, upper = upper, lower
im = Image.open(input_loc)
im = im.crop(( left, upper, right, lower))
pygame.display.quit()
im.save(output_loc)
The answer by samplebias was great for me. samplebias 的答案对我来说很棒。 I extended it for the large images I am working with by adding zoom and pan capabilities.
我通过添加缩放和平移功能为我正在使用的大图像扩展了它。
import pygame, sys
from pygame.locals import K_a, K_s,K_w,K_d,K_LEFTBRACKET,K_RIGHTBRACKET
from PIL import Image
pygame.init()
BG_COLOR = (0,0,0)
def displayRect(screen, px, topleft, prior,pos,scale):
# ensure that the rect always has positive width, height
#topleft = [(val-pos[i])/scale for i,val in enumerate(topleft)]
topleft = [(val/scale-pos[i]) for i,val in enumerate(topleft)]
x, y = topleft
bottomright = pygame.mouse.get_pos()
width = bottomright[0] - topleft[0]
height = bottomright[1] - topleft[1]
if width < 0:
x += width
width = abs(width)
if height < 0:
y += height
height = abs(height)
# eliminate redundant drawing cycles (when mouse isn't moving)
current = x, y, width, height
if not (width and height):
return current
if current == prior:
return current
# draw transparent box and blit it onto canvas
rect = px.get_rect()
px = pygame.transform.scale(px,[rect.width/scale, rect.height/scale])
screen.blit(px, (rect[0]-pos[0],rect[1]-pos[1]))
im = pygame.Surface((width, height))
im.fill((128, 128, 128))
pygame.draw.rect(im, (32, 32, 32), im.get_rect(), 1)
im.set_alpha(128)
screen.blit(im, (x, y))
pygame.display.flip()
# return current box extents
return (x, y, width, height)
def setup(px):
screen = pygame.display.set_mode( px.get_rect()[2:] )
screen.blit(px, px.get_rect())
pygame.display.flip()
return screen, px
def move(pos,scale,px,screen):
x,y = pos
#print pos,x
rect = px.get_rect()
screen.fill(BG_COLOR)
px = pygame.transform.scale(px,[rect.width/scale, rect.height/scale])
screen.blit(px, (rect[0]-x,rect[1]-y))
pygame.display.flip()
#px.rect.topleft = pr.rect.topleft[0] - x,
def mainLoop(screen, px, filelist):
topleft = bottomright = prior = None
n=0
scale = 1
pos = [0,0]
while n!=1:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP:
if not topleft:
topleft = [(val+pos[i])*scale for i,val in enumerate(event.pos)]
print "tr: ",topleft
else:
bottomright = [(val+pos[i])*scale for i,val in enumerate(event.pos)]
print "br: ",bottomright
n=1
if event.type == pygame.KEYDOWN and event.key == K_a:
pos = [pos[0]-200,pos[1]]
move(pos,scale,px,screen)
if event.type == pygame.KEYDOWN and event.key == K_d:
pos = [pos[0]+200,pos[1]]
move(pos,scale,px,screen)
if event.type == pygame.KEYDOWN and event.key == K_w:
pos = [pos[0],pos[1]-200]
move(pos,scale,px,screen)
if event.type == pygame.KEYDOWN and event.key == K_s:
pos = [pos[0],pos[1]+200]
move(pos,scale,px,screen)
if event.type == pygame.KEYDOWN and event.key == K_RIGHTBRACKET:
scale = scale/1.25
move(pos,scale,px,screen)
if event.type == pygame.KEYDOWN and event.key == K_LEFTBRACKET:
scale = scale*1.25
move(pos,scale,px,screen)
if topleft:
prior = displayRect(screen, px, topleft, prior,pos,scale)
return ( topleft + bottomright )
Use the main function samplebias provided.使用提供的主要function 样本偏差。
Thanks Stack Overflow!感谢堆栈溢出!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.