我正在Django开发一个图像上传程序。图像上传并保存在磁盘上后, 我试图调整保存图像的大小,同时保持它的纵横比。我正在使用枕头进行图像处理/调整大小。当我试图调整图像大小时,问题就出现了,即使调整大小的图像的纵横比与原始图像的纵横比相同,它还是会被像素化。在
原始保存图像: https://www.dropbox.com/s/80yk6tnwt3xnoun/babu_980604.jpeg
调整像素图像大小: https://www.dropbox.com/s/bznodpk4t4xlyqp/babu_736302.large.jpeg
我试过在google上搜索这个问题,也查过stackoverflow上的其他相关链接
像
How do I resize an image using PIL and maintain its aspect ratio?
Resize image maintaining aspect ratio AND making portrait and landscape images exact same size?
但问题依然存在。在
版本:
Django=1.6.4
枕头=2.4.0
一切都在virtualenv内部设置好了。请帮忙!在
PS:我是Python/Django世界的新手
下面是我的代码片段:
import json
import os
import hashlib
from datetime import datetime
from operator import itemgetter
import random
from random import randint
from django.views.decorators.csrf import csrf_exempt, csrf_protect
from django.http import (HttpResponse, HttpResponseRedirect)
from django.core.context_processors import csrf
from django.core.files.images import get_image_dimensions
from django.shortcuts import render, redirect
from django.forms.models import model_to_dict
from django.views.decorators.csrf import csrf_exempt
from PIL import Image, ImageOps
from django.views.decorators.csrf import csrf_exempt, csrf_protect
import settings
from hashlib import md5
from django import forms
from beardedavenger.models import *
from django.views.decorators.http import require_POST
import pdb
import requests
def imagehandler(requests):
if requests.method == 'POST':
filename = requests.FILES['file'].name
file_extension = filename.split('.')[len(filename.split('.')) - 1].lower()
errors = []
username = 'nit'
global random
#allowed image types are png, jpg, jpeg, gif
if file_extension not in settings.IMAGE_FILE_TYPES:
errors.append('The image file you provided is not valid. Only the following extensions are allowed: %s' % ', '.join(settings.IMAGE_FILE_TYPES))
else:
image = requests.FILES['file']
image_w, image_h = get_image_dimensions(image)
rand = str(random.randint(100000,999999))
with open(settings.MEDIA_ROOT + username + '_' + rand + '.jpeg', 'wb+') as destination:
for chunk in requests.FILES['file'].chunks():
destination.write(chunk)
large_size = (1920, 1200)
infile = settings.MEDIA_ROOT + username + '_' + rand + ".jpeg"
large_file = settings.MEDIA_ROOT + username + '_' + rand +".large"
try:
im = Image.open(infile)
base_width = large_size[0]
aspect_ratio = float(image_w / float(image_h))
new_height = int(base_width / aspect_ratio)
if new_height < 1200:
final_width = base_width
final_height = new_height
else:
final_width = int(aspect_ratio * large_size[1])
final_height = large_size[1]
final_size = (final_width, final_height)
imaged = im.resize((final_width, final_height), Image.ANTIALIAS)
# imaged = ImageOps.fit(im, final_size, Image.ANTIALIAS, centering = (0.5,0.5))
imaged.save(large_file, "JPEG", quality=90)
except IOError:
errors.append('error while resizing image')
if not errors:
response = HttpResponse(json.dumps({'status': 'success','filename': filename }),
mimetype="application/json")
else:
response = HttpResponse(json.dumps({'status': 'failure','errors': errors,'message': 'Error uploading Picture. '}),
mimetype="application/json")
return response
else:
return render(requests, 'upload.html')
更新:
我用枕头来调整和压缩我的图像。即使保持了纵横比,在调整大小时,图像中也会引入一定程度的暗沉[与原始图像相比,抗锯齿比要求的要多]。我把我的处理库切换到ImageMagick(有很多帖子建议不要这样做!)以及Wand API(文档.wand-py.org/en/07.3/索引.html),以处理我的图像。这变化真是妙不可言!在
通过这个代码,我得到了这个图像(Python2.7,Pillow2.4.0),它没有像素化。在
这与您的代码的主要区别在于它直接从打开的图像中获取},而不是{},后者的实现没有显示。在
image_w
和{代码中的一些小问题:
您可以在
with open(...)
之前设置infile
,并在那里使用它。final_size
未使用并且可以删除,或者在im.resize()
中使用它。base_width
可以替换为large_size[0]
,因为您在其他地方也使用large_size[1]
。image
设置为requests.FILES['file']
,但您也可以直接使用requests.FILES['file']
。您可以重用image
。global random
可能不需要。相关问题 更多 >
编程相关推荐