كيف يمكنني تغيير حجم الصورة باستخدام PIL والحفاظ على نسبة جانبها؟
-
07-07-2019 - |
سؤال
هل هناك طريقة واضحة للقيام بذلك أن أنا في عداد المفقودين؟ أنا مجرد محاولة لجعل الصور المصغرة.
المحلول
وتحديد الحد الأقصى لحجم.
ثم، حساب نسبة تغيير الحجم من خلال اتخاذ 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
نصائح أخرى
وهذا السيناريو سوف تغيير حجم صورة (somepic.jpg) باستخدام PIL (مكتبة التصوير بيثون) إلى عرض 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')
وأوصي أيضا باستخدام طريقة مصغرة PIL، لأن ذلك يزيل كل متاعب نسبة منك.
وتلميح واحد مهم، على الرغم من: استبدال
im.thumbnail(size)
مع
im.thumbnail(size,Image.ANTIALIAS)
وبشكل افتراضي، يستخدم PIL مرشح Image.NEAREST لتغيير حجم مما يؤدي إلى أداء جيد، ولكن سوء نوعية.
ومقرها فيtomvon، I الانتهاء من استخدام ما يلي:
وتغيير حجم العرض:
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)
و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
إذا كنت تحاول الحفاظ على نفس نسبة الارتفاع، ثم لن تغيير حجم بعض نسبة مئوية من الحجم الأصلي؟
وعلى سبيل المثال، نصف الحجم الأصلي
half = 0.5
out = im.resize( [int(half * s) for s in im.size] )
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
وبلدي سبيل المثال القبيح.
وظيفة الحصول على ملف مثل: "الموافقة المسبقة عن علم [0-9a زي] [إضافة]"، حجمها إلى 120x120، قسم ينتقل إلى مركز وحفظ إلى "منظمة البن الدولية [0-9a زي] [إضافة]". يعمل مع صورة والمناظر الطبيعية:
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:])
وهناك طريقة بسيطة للحفاظ على نسب مقيدة وتمرير عرض ماكس / الارتفاع. ليس أجمل ولكن يحصل على هذه المهمة ومن السهل أن نفهم:
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
وفيما يلي الثعبان النصي يستخدم هذه الوظيفة لتشغيل الصور دفعة تغيير الحجم.
وكنت أحاول أن تغيير بعض الصور لشريط فيديو عرض الشرائح وبسبب ذلك، أردت ليس فقط كحد أقصى واحد البعد، ولكن عرض ماكس <م> و م> ارتفاع ماكس (حجم إطار الفيديو) .
وكان هناك دائما إمكانية فيديو صورة ...
كانت الطريقة 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)
إذا كنت لا تريد / لا يكون هناك حاجة لفتح صورة مع وسادة، واستخدام هذه:
from PIL import Image
new_img_arr = numpy.array(Image.fromarray(img_arr).resize((new_width, new_height), Image.ANTIALIAS))
وأنا resizeed الصورة في مثل هذه الطريقة وانها تعمل بشكل جيد جدا
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)
ومجرد تحديث هذا السؤال مع المجمع أكثر حداثة هذه المكتبة يلتف سادة (مفترق 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()
وأكوام من الأمثلة في الرابط أعلاه.