使用Python进行图像裁剪 [英] Image Cropping using Python

查看:702
本文介绍了使用Python进行图像裁剪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Python编码的新手,我正在编写一个程序,在其中我将裁剪输入的图像,然后将其保存在某个位置。现在,我可以使用PIL和pygame的组合来做到这一点。但问题是,当我从打开的pygame窗口中选择图像时,选择区域是完全不透明的,我无法看到我正在选择的区域。这给我的老板带来了问题,他希望能够在他选择的时候看透它。为了让你们更好地理解这个问题,我在这里写代码:

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. Now, I am being able to do this using a combination of PIL and 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. 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)

感谢任何帮助。问候。

推荐答案

我快速浏览并解决了其他一些问题。基本上我的更改是这样做的:

I took a quick look and fixed a few other problems along the way. Essentially my changes do this:


  • 在临时图像上绘制边界框,设置其alpha透明度,然后在顶部插入blit主图像。

  • 避免无关的绘图周期(当鼠标不移动时,再次绘制相同图像时没有任何意义)。

  • 确保宽度和高度始终为正。如果通过向左或向上拖动鼠标来绘制矩形,则代码最终会显示负宽度和/或高度,从而在尝试编写最终图像时引发异常。

以下是运行固定代码的屏幕截图:

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)

和第2部分(连接到上面):

And part 2 (concatenate to the above):

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)

这篇关于使用Python进行图像裁剪的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆