0

有没有简单的方法来做到这一点? 在Python中,我创建了一个脚本来从图像中获取一个“方块”......基于中心。如何拍摄图像并获取从中心剪切的3x2比例图像?

但是,这导致我的一些脑细胞死亡。基于中心有没有简单的方法来做到这一点3×2(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 

有没有脚本在线,可以做我需要的?

+1

你为什么要压制异常?除非您确切知道发生异常的原因以及如何处理它,否则您应该让它冒泡,否则您将隐藏需要了解的错误或系统故障。 – jammycakes 2010-11-04 14:43:21

+0

@jammycakes:不仅如此,它的写入方式并不能完全防止它引发异常,因为在函数结束时执行返回操作的'new_file'仍然可能还没有被定义。 – martineau 2010-11-08 16:43:27

回答

1

使用被定义为代码imagex /图像j的纵横比,因此使用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()更好地描述 -

+0

我原来的版本错了,太长了。这个更好。 – 2010-11-04 08:31:53

0

首先,因为它的作用是letterbox图像(不管具体高度/宽度[宽高比]的参与)的函数的名称是误导它能做什么。

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)可能是整数,但我明确地将其作为浮点提醒。将它作为两个独立的整数传递并在内部计算比率可能会更好。最后,我注意到你的示例脚本有一些看起来像试图创建图像缩略图的可见痕迹,所以我对相关问题What's the simplest way in Python to resize an image to a given bounded area?的回答可能也是有意义的(也可能集成到这个功能没有太多的麻烦)。