web-dev-qa-db-ja.com

PILを使用して画像のサイズを変更し、その縦横比を維持するにはどうすればよいですか?

私が見逃していることをこれを行うための明白な方法はありますか?サムネイルを作っているだけです。

348
saturdayplace

最大サイズを定義してください。次に、min(maxwidth/width, maxheight/height)を使用してサイズ変更比率を計算します。

適切なサイズはoldsize*ratioです。

もちろんこれを行うためのライブラリメソッドもあります:メソッドImage.thumbnail
以下は PILのドキュメント からの(編集された)例です。

import os, sys
import Image

size = 128, 128

for infile in sys.argv[1:]:
    outfile = os.path.splitext(infile)[0] + ".thumbnail"
    if infile != outfile:
        try:
            im = Image.open(infile)
            im.thumbnail(size, Image.ANTIALIAS)
            im.save(outfile, "JPEG")
        except IOError:
            print "cannot create thumbnail for '%s'" % infile
409
gnud

このスクリプトは、PIL(Python Imaging Library)を使用して画像(somepic.jpg)を300ピクセルの幅と新しい幅に比例した高さにサイズ変更します。これは、元の幅の300ピクセルが何パーセントであるか(img.size [0])を決定してから、元の高さ(img.size [1])にそのパーセントを掛けて算出します。画像のデフォルトの幅を変更するには、 "basewidth"を他の数値に変更します。

from PIL import Image

basewidth = 300
img = Image.open('somepic.jpg')
wpercent = (basewidth/float(img.size[0]))
hsize = int((float(img.size[1])*float(wpercent)))
img = img.resize((basewidth,hsize), Image.ANTIALIAS)
img.save('sompic.jpg') 
197
tomvon

それはあなたからすべての比率の煩わしさを削除するので、私はまたPILのサムネイル方式を使用することをお勧めします。

ただし、重要なヒントが1つあります。

im.thumbnail(size)

im.thumbnail(size,Image.ANTIALIAS)

デフォルトでは、PILはサイズ変更にImage.NEARESTフィルタを使用します。これにより、パフォーマンスは向上しますが、品質は低下します。

53
Franz

@tomvonに基づいて、私は次のものを使い終えました:

幅の変更:

new_width  = 680
new_height = new_width * height / width 

高さの変更:

new_height = 680
new_width  = new_height * width / height

それからちょうど:

img = img.resize((new_width, new_height), Image.ANTIALIAS)
26
muZk

PILにはすでに画像をトリミングするオプションがあります

img = ImageOps.fit(img, size, Image.ANTIALIAS)
from PIL import Image

img = Image.open('/your iamge path/image.jpg') # image extension *.png,*.jpg
new_width  = 200
new_height = 300
img = img.resize((new_width, new_height), Image.ANTIALIAS)
img.save('output image name.png') # format may what u want ,*.png,*jpg,*.gif
15

同じ縦横比を維持しようとしているのなら、元のサイズの何パーセントかのサイズを変更しないでください。

たとえば、元のサイズの半分

half = 0.5
out = im.resize( [int(half * s) for s in im.size] )
11
Chris Cameron
from PIL import Image
from resizeimage import resizeimage

def resize_file(in_file, out_file, size):
    with open(in_file) as fd:
        image = resizeimage.resize_thumbnail(Image.open(fd), size)
    image.save(out_file)
    image.close()

resize_file('foo.tif', 'foo_small.jpg', (256, 256))

私はこのライブラリを使います。

pip install python-resize-image
3
guettli

制約された比率を保ち、最大の幅/高さを渡すための簡単な方法。最もきれいではありませんが、仕事を終わらせて、理解するのは簡単です:

def resize(img_path, max_px_size, output_folder):
    with Image.open(img_path) as img:
        width_0, height_0 = img.size
        out_f_name = os.path.split(img_path)[-1]
        out_f_path = os.path.join(output_folder, out_f_name)

        if max((width_0, height_0)) <= max_px_size:
            print('writing {} to disk (no change from original)'.format(out_f_path))
            img.save(out_f_path)
            return

        if width_0 > height_0:
            wpercent = max_px_size / float(width_0)
            hsize = int(float(height_0) * float(wpercent))
            img = img.resize((max_px_size, hsize), Image.ANTIALIAS)
            print('writing {} to disk'.format(out_f_path))
            img.save(out_f_path)
            return

        if width_0 < height_0:
            hpercent = max_px_size / float(height_0)
            wsize = int(float(width_0) * float(hpercent))
            img = img.resize((max_px_size, wsize), Image.ANTIALIAS)
            print('writing {} to disk'.format(out_f_path))
            img.save(out_f_path)
            return

これは pythonスクリプト です。この関数はバッチ画像のサイズ変更を実行します。

2
AlexG

私はスライドショービデオのためにいくつかの画像をリサイズしようとしていました、そしてそのために、私はただ1つの最大寸法ではなく、最大幅最大高さ(ビデオフレームのサイズ)が欲しいです。
そして、ポートレートビデオの可能性は常にありました...
Image.thumbnailメソッドは有望でしたが、私はそれをより小さな画像にすることはできませんでした。

そのため、ここで(または他の場所で)それを実行するための明白な方法が見つからなかった後、私はこの関数を書いて、来るべきもののためにここにそれを入れました:

from PIL import Image

def get_resized_img(img_path, video_size):
    img = Image.open(img_path)
    width, height = video_size  # these are the MAX dimensions
    video_ratio = width / height
    img_ratio = img.size[0] / img.size[1]
    if video_ratio >= 1:  # the video is wide
        if img_ratio <= video_ratio:  # image is not wide enough
            width_new = int(height * img_ratio)
            size_new = width_new, height
        else:  # image is wider than video
            height_new = int(width / img_ratio)
            size_new = width, height_new
    else:  # the video is tall
        if img_ratio >= video_ratio:  # image is not tall enough
            height_new = int(width / img_ratio)
            size_new = width, height_new
        else:  # image is taller than video
            width_new = int(height * img_ratio)
            size_new = width_new, height
    return img.resize(size_new, resample=Image.LANCZOS)
2
embryo

私の醜い例.

関数は「pic [0-9a-z]。[extension]」のようなファイルを取得し、120x120にリサイズし、セクションを中央に移動して「ico [0-9a-z]。[extension]」に保存しますと風景:

def imageResize(filepath):
    from PIL import Image
    file_dir=os.path.split(filepath)
    img = Image.open(filepath)

    if img.size[0] > img.size[1]:
        aspect = img.size[1]/120
        new_size = (img.size[0]/aspect, 120)
    else:
        aspect = img.size[0]/120
        new_size = (120, img.size[1]/aspect)
    img.resize(new_size).save(file_dir[0]+'/ico'+file_dir[1][3:])
    img = Image.open(file_dir[0]+'/ico'+file_dir[1][3:])

    if img.size[0] > img.size[1]:
        new_img = img.crop( (
            (((img.size[0])-120)/2),
            0,
            120+(((img.size[0])-120)/2),
            120
        ) )
    else:
        new_img = img.crop( (
            0,
            (((img.size[1])-120)/2),
            120,
            120+(((img.size[1])-120)/2)
        ) )

    new_img.save(file_dir[0]+'/ico'+file_dir[1][3:])
2
Nips

Pillowで画像を開く必要がない、または必要がない場合は、次のようにしてください。

from PIL import Image

new_img_arr = numpy.array(Image.fromarray(img_arr).resize((new_width, new_height), Image.ANTIALIAS))
1
hoohoo-b

この質問をもっと近代的なラッパーで更新するだけです。このライブラリはPillow(PILのフォーク)をラップしています。 https://pypi.org/project/python-resize-image/

あなたにこのようなことをさせてくれます: -

from PIL import Image
from resizeimage import resizeimage

fd_img = open('test-image.jpeg', 'r')
img = Image.open(fd_img)
img = resizeimage.resize_width(img, 200)
img.save('test-image-width.jpeg', img.format)
fd_img.close()

上記のリンクでより多くの例を積み重ねます。

0
Shanness

このように画像のサイズを変更したところ、うまく機能しました。

from io import BytesIO
from Django.core.files.uploadedfile import InMemoryUploadedFile
import os, sys
from PIL import Image


def imageResize(image):
    outputIoStream = BytesIO()
    imageTemproaryResized = imageTemproary.resize( (1920,1080), Image.ANTIALIAS) 
    imageTemproaryResized.save(outputIoStream , format='PNG', quality='10') 
    outputIoStream.seek(0)
    uploadedImage = InMemoryUploadedFile(outputIoStream,'ImageField', "%s.jpg" % image.name.split('.')[0], 'image/jpeg', sys.getsizeof(outputIoStream), None)

    ## For upload local folder
    fs = FileSystemStorage()
    filename = fs.save(uploadedImage.name, uploadedImage)
0
Siddhartha