问题描述
|
我是Python编码的新手,我正在编写一个程序,其中将裁剪输入的图像,然后将其保存在某个位置。现在,我可以结合使用PIL和pygame来做到这一点。但是问题是,当我从打开的pygame窗口中选择图像时,选择区域是完全不透明的,并且无法看透正在选择的区域。这给我的老板带来了麻烦,他希望能够按自己的选择进行查看。为了让你们更好地理解问题,我在这里编写代码:
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,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,lower))
pygame.display.quit()
im.save(output_loc)
任何帮助表示赞赏。问候。
解决方法
我快速浏览并解决了其他一些问题。本质上,我的更改是这样做的:
在临时图像上绘制边界框,设置其Alpha透明度,然后将其在主图像上方变白。
避免不必要的绘制周期(当鼠标不动时,再次绘制同一图像毫无意义)。
确保宽度和高度始终为正。如果通过向左或向上拖动鼠标来绘制矩形,则您的代码将以负的宽度和/或高度结尾,从而在尝试写入最终图像时引发异常。
这是运行固定代码的屏幕截图:
我将代码分为两部分,以避免出现滚动条:
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,height)
第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,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,lower))
pygame.display.quit()
im.save(output_loc)
,samplebias的答案对我来说很棒。通过添加缩放和平移功能,我将其扩展到了正在处理的大图像。
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)
def displayRect(screen,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,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)
def setup(px):
screen = pygame.display.set_mode( px.get_rect()[2:] )
screen.blit(px,px
def move(pos,scale,screen):
x,y = pos
#print pos,x
rect = px.get_rect()
screen.fill(BG_COLOR)
px = pygame.transform.scale(px,(rect[0]-x,rect[1]-y))
pygame.display.flip()
#px.rect.topleft = pr.rect.topleft[0] - x,def mainLoop(screen,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,screen)
if event.type == pygame.KEYDOWN and event.key == K_d:
pos = [pos[0]+200,screen)
if event.type == pygame.KEYDOWN and event.key == K_w:
pos = [pos[0],pos[1]-200]
move(pos,screen)
if event.type == pygame.KEYDOWN and event.key == K_s:
pos = [pos[0],pos[1]+200]
move(pos,screen)
if event.type == pygame.KEYDOWN and event.key == K_RIGHTBRACKET:
scale = scale/1.25
move(pos,screen)
if event.type == pygame.KEYDOWN and event.key == K_LEFTBRACKET:
scale = scale*1.25
move(pos,screen)
if topleft:
prior = displayRect(screen,scale)
return ( topleft + bottomright )
使用提供的主要功能samplebias。
谢谢堆栈溢出!