Как я могу сделать снимок и обрезать изображение с соотношением 3х2 от центра? - PullRequest
0 голосов
/ 04 ноября 2010

Есть ли простой способ сделать это? В Python я создал скрипт для получения «квадратной рамки» из изображения ... на основе центра.

Однако это убило некоторые клетки моего мозга. Есть ли простой способ сделать это для 3x2 (3 ширины, 2 высоты), основываясь на центре?

Это мой скрипт "квадратный ящик", но я не хочу его модифицировать для 3х2.

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

Есть ли онлайн-скрипт, который может сделать то, что мне нужно?

Ответы [ 2 ]

2 голосов
/ 04 ноября 2010

Используйте соотношение сторон, которое определяется как 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

Возможно, вы захотите проверитьошибки округления в некоторый момент, но в противном случае это делает.

0 голосов
/ 04 ноября 2010

Прежде всего, название вашей функции вводит в заблуждение, потому что это не почтовый ящик изображения (независимо от конкретной высоты / ширины [соотношения сторон]) -поэтому здесь он был переименован в 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) могло бы быть целое число, но я явно сделал это с плавающей точкой в ​​качестве напоминания.Возможно, было бы лучше передать его в виде двух отдельных целых чисел и вычислить соотношение для внутреннего использования.

Наконец, я заметил, что в вашем примере сценария есть некоторые видимые следы того, что выглядит как попытка создать эскиз изображения,поэтому мой ответ на связанный вопрос Какой самый простой способ в Python изменить размер изображения до заданной ограниченной области? также может представлять интерес (и, вероятно, может быть интегрирован в эту функцию безслишком много проблем).

...