Python 如何拍摄图像并从中心裁剪3x2比例的图像?

Python 如何拍摄图像并从中心裁剪3x2比例的图像?,python,algorithm,image-processing,python-imaging-library,Python,Algorithm,Image Processing,Python Imaging Library,有没有一个简单的方法可以做到这一点? 在Python中,我创建了一个脚本,从图像中获取一个“方形框”…基于中心 然而,这杀死了我的一些脑细胞。对于3x2(3宽2高),是否有一种简单的方法可以基于中心进行此操作 这是我的“方盒”脚本,但我不想为3x2修改它 def letterbox(f,thumb_w=None,thumb_h=None): try: im = Image.open(StringIO(f)) imagex = int(im.size[0])

有没有一个简单的方法可以做到这一点? 在Python中,我创建了一个脚本,从图像中获取一个“方形框”…基于中心

然而,这杀死了我的一些脑细胞。对于3x2(3宽2高),是否有一种简单的方法可以基于中心进行此操作

这是我的“方盒”脚本,但我不想为3x2修改它

def letterbox(f,thumb_w=None,thumb_h=None):
    try:
        im = Image.open(StringIO(f))
        imagex = int(im.size[0])
        imagey = int(im.size[1])
        thumb_size = (thumb_w,thumb_h) #what if it is too small!?? fix it.
        if imagex > imagey:
            setlen = imagey
            left = (imagex - setlen)/2
            top = 0
            height = setlen
            width = setlen
        if imagey > imagex:
            setlen = imagex
            left = 0
            top = (imagey - setlen)/2
            heigth = setlen
            width = setlen
        if imagex == imagey:
            left = 0
            top = 0
            height = imagey
            width = imagex
        box = (left,top,left+width,top+height)
        im = im.crop(box)
        #im.thumbnail(thumb_size,Image.ANTIALIAS)
        new_file = StringIO()
        im.save(new_file,'JPEG')
        new_file.seek(0)
    except Exception, e:
        pass
    return new_file

有在线脚本可以满足我的需要吗?

使用定义为imagex/imagey的纵横比,因此使用3/2表示3:2,16/9表示16:9等

def letterbox(f,aspect_ratio=1):
    try:
        im = Image.open(StringIO(f))
        imagex = int(im.size[0])
        imagey = int(im.size[1])
        width = min(imagex, imagey*aspect_ratio)
        height = min(imagex/aspect_ratio, imagey)
        left =(imagex - width)/2
        top = (imagey - height)/2
        box = (left,top,left+width,top+height)
        im = im.crop(box)
        new_file = StringIO()
        im.save(new_file,'JPEG')
        new_file.seek(0)
    except Exception, e:
        pass
    return new_file

您可能希望在某一点上检查舍入错误,但在其他情况下就可以了。

首先,函数的名称是误导性的,因为它所做的是而不是图像(不管涉及的具体高度/宽度[纵横比])——因此在这里它被重命名为
aspectcrop()
以更好地描述它的功能

def aspectcrop(f, ratio=1.0):
    try:
        im = Image.open(StringIO(f))
        imagewidth,imageheight = im.size

        # determine the dimensions of a crop area
        # which is no wider or taller than the image
        if int(imagewidth*ratio) > imageheight:
            cropheight,cropwidth = imageheight,int(imageheight/ratio)
        else:
            cropwidth,cropheight = imagewidth,int(imagewidth*ratio)

        # center the crop area on the image (dx and/or dy will be zero)
        dx,dy = (imagewidth-cropwidth)/2,(imageheight-cropheight)/2

        # crop, save, and return image data
        im = im.crop((dx,dy,cropwidth+dx,cropheight+dy))
        new_file = StringIO()
        im.save(new_file,'JPEG')
        new_file.seek(0)
    except Exception, e:
        new_file = None # prevent exception on return
        pass
    return new_file
如果传递给它的任何方面
ratio
参数自然不是一个整数,请确保它是浮点型的,如
3./2.
不是
3/2
。默认值(
1.0
)可以是整数,但我明确地将其设为浮点数作为提醒。最好将其作为两个独立的整数传入,并在内部计算比率


最后,我注意到您的示例脚本中有一些看起来像是试图创建图像缩略图的可见痕迹,因此我对相关问题的回答可能也会引起兴趣(并且可能会在不太麻烦的情况下集成到此函数中)。

为什么要抑制异常?除非您确切知道异常发生的原因以及如何处理,否则您应该让它冒泡出来,否则您将隐藏您需要知道的bug或系统故障。@jammycakes:不仅如此,它的编写方式并不能完全防止它导致异常,因为在函数末尾执行返回它的尝试时,
new_file
仍有可能尚未定义。