2012-02-01 19 views
11

は、現在、私が使用しています:縦横比を維持した画像のサイズを変更し、縦長画像と横長画像を正確に同じサイズにしますか?

os.chdir(album.path) 
    images = glob.glob('*.*') 

    # thumbs size 
    size = 80,80 

    for image in images: 
     #create thumb 
     file, ext = os.path.splitext(image) 
     im = Image.open(os.path.join(album.path,image)) 
     im.thumbnail(size, Image.ANTIALIAS) 
     thumb_path = os.path.join(album.path, 'thumbs', file + ".thumb" + ".jpeg") 
     im.save(thumb_path) 

を、これは動作しますが、私は、異なるサイズの画像(一部は肖像画であり、一部はランドスケープある)で終わるが、私はすべての画像が正確なサイズを持っていると思います。多分合理的な切り取り?

UPDATE:

私は画像の小さな部分を切り取る気にしません。私が合理的な切り抜きを言ったとき、私はこのような何かを意味していました。

if image is portrait: 
    make width 80px 
    crop the height (will be more than 80px) 
else if image is landscape: 
    make height 80px 
    crop the width to 80px (will be more than 80px) 
+0

は、マニュアルを読んで考えてみましょう。 'thumnail'メソッドは画像のアスペクトを保存することを意味します。すべての画像が同じアスペクト比を持つわけではないので、明らかに両方を持つことはできません。レシオを維持しないで再スケーリングしたい場合は、 'resize'の使用を検討してください。 –

+1

余分な領域を一定の色で塗りつぶしたい場合、彼は同じサイズにすることができます。そうすれば、4x3または16x9または任意のアスペクト画像を80x80の所定の次元に収めることができます – jdi

+0

残念ながら、クロッピングのための「感覚的」を定義する標準的な方法はありません。画像から四角形を切り抜きたいと思うように思えます。つまり、本当に残したい部分を切り取る危険性があります。 –

答えて

18

はイメージのためのパッド入りのフィットを行う上で私の感想です:

#!/usr/bin/env python 

from PIL import Image, ImageChops 

F_IN = "/path/to/image_in.jpg" 
F_OUT = "/path/to/image_out.jpg" 

size = (80,80) 

image = Image.open(F_IN) 
image.thumbnail(size, Image.ANTIALIAS) 
image_size = image.size 

thumb = image.crop((0, 0, size[0], size[1])) 

offset_x = max((size[0] - image_size[0])/2, 0) 
offset_y = max((size[1] - image_size[1])/2, 0) 

thumb = ImageChops.offset(thumb, offset_x, offset_y) 
thumb.save(F_OUT) 

まずサムネイル操作を使用して、イメージを元の範囲内に戻し、そのアスペクトを保持します。その後、元の画像が正方形でない限り、実際には境界の大きさを塗りつぶして元の画像に戻します。イメージは中央にオフセットされているため、黒いパディングが発生しますが、イメージのクロッピングは発生しません。

エッジで重要な画像データを失うことなく適切な中央の切り抜きを実際に行うことができない限り、パッディングフィットのアプローチが効果的です。

更新ここ

は、センタークロップやパッドのフィットのいずれかを行うことができますバージョンです。あなたはcropTrueからTrueにとupscaleは常に埋めるアップするためにスペースを設定する必要があります簡単サムネイルを使用している場合

#!/usr/bin/env python 

from PIL import Image, ImageChops, ImageOps 

def makeThumb(f_in, f_out, size=(80,80), pad=False): 

    image = Image.open(f_in) 
    image.thumbnail(size, Image.ANTIALIAS) 
    image_size = image.size 

    if pad: 
     thumb = image.crop((0, 0, size[0], size[1])) 

     offset_x = max((size[0] - image_size[0])/2, 0) 
     offset_y = max((size[1] - image_size[1])/2, 0) 

     thumb = ImageChops.offset(thumb, offset_x, offset_y) 

    else: 
     thumb = ImageOps.fit(image, size, Image.ANTIALIAS, (0.5, 0.5)) 

    thumb.save(f_out) 


source = "/path/to/source/image.JPG" 

makeThumb(source, "/path/to/source/image_padded.JPG", pad=True) 
makeThumb(source, "/path/to/source/image_centerCropped.JPG", pad=False) 
+0

これは本当に私が@jdiが必要なものに近いです、ありがとう!どのように私はチョップに変更し、パディングを挿入しないのですか? (画像の塊を失っても) – thyagx

+0

@thyagx - そこに行くよ! – jdi

+1

パーフェクト、まさに私が必要なもの!ありがとう@jdi! – thyagx

2

明らかに、イメージを切り抜くか、パッドする必要があります。あなたはサムネイル(未テスト)のアスペクト比に応じて最大の中心に作物を取得するには、以下のような何かを行うことができます:ここでは

aspect = lambda size: float(size[0])/float(size[1]) 
sa = aspect(size) 
if aspect(im.size) > sa: 
    width = int(sa * im.size[1]) 
    left = (im.size[0] - width)/2 
    im = im.crop((left, 0, left + width, im.size[1])) 
else: 
    height = int(im.size[0]/sa) 
    top = (im.size[1] - height)/2 
    im = im.crop((0, top, im.size[0], top + height)) 
im.thumbnail(size, Image.ANTIALIAS) 
+0

この例にはいくつかのバグがあります。 im.crop()は適切な位置で切り取られません。イメージオブジェクトをそれ自身に戻す必要があります。作物の引数はボックスタプルでなければならないので、それらを()で囲む必要があります。あなたはフロートを作物に渡しています。 int(width)とint(height)を行う必要があります。また、同じことをする 'im = ImageOps.fit(im、size、Image.ANTIALIAS、(0.5、0.5))'メソッドが組み込まれているので、このすべては必要ではありません。 – jdi

0

(正確に同じ寸法を有しています)。

例:IMAGE_2はIMAGE_1寸法に収まります:

thumbnailer = get_thumbnailer(image_2) 
    thumbnail = thumbnailer.generate_thumbnail(thumbnail_options={ 
     'crop': True, 
     'upscale': True, 
     'size': image_1.size 
    }) 
    image_2 = thumbnail.image 
関連する問題