Кадрирование изображений с использованием Python

Я новичок в кодировании 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, 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) 

Любая помощь приветствуется. С уважением.

2 Solutions collect form web for “Кадрирование изображений с использованием Python”

Я быстро посмотрел и исправил еще несколько проблем. По существу мои изменения делают это:

  • Нарисуйте ограничивающий прямоугольник на временном изображении, установите его альфа-прозрачность, а затем нажмите на верх над основным изображением.
  • Избегайте посторонних циклов рисования (когда мышь не движется, нет смысла снова рисовать одно и то же изображение).
  • Убедитесь, что ширина и высота всегда положительны. Если прямоугольник рисуется путем перетаскивания мыши влево или вверх, ваш код будет иметь отрицательную ширину и / или высоту, создавая исключение при попытке записать окончательное изображение.

Вот скриншот запуска фиксированного кода:

введите описание изображения здесь

Я разделил код на две части, чтобы избежать полос прокрутки:

 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) 

И часть 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) 

Ответ 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,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 ) 

Используйте основные функции samplebias.

Благодаря переполнению стека!

Python - лучший язык программирования в мире.