我正在Django开发一个图像上传器.将图像上传并保存在磁盘上后,我正在尝试调整已保存图像的大小,同时保持其宽高比.我正在使用Pillow进行图像处理/调整大小.当我尝试调整图像大小时会出现问题,即使调整大小的图像的宽高比与原始图像的宽高比相同,也会出现像素化现象.
原始保存的图像:https: //www.dropbox.com/s/80yk6tnwt3xnoun/babu_980604.jpeg
调整大小的像素化图像:https: //www.dropbox.com/s/bznodpk4t4xlyqp/babu_736302.large.jpeg
我试过谷歌搜索这个问题,并检查了stackoverflow上的其他相关链接,
喜欢
如何使用PIL调整图像大小并保持其纵横比?
调整图像保持纵横比并使纵向和横向图像完全相同的大小?
但问题仍然存在.
版本:
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')
更新:
我正在使用Pillow来调整和压缩我的图像.即使保持纵横比,在调整大小时图像中也会引入一定量的暗淡[与原始图像相比具有比所需更多的抗锯齿].我将处理库切换到ImageMagick(针对许多帖子,建议不要!)以及Wand API(docs.wand-py.org/en/0.3.7/index.html)来处理我的图像.这种变化就像一个魅力!
使用此代码,我得到了这个没有像素化的图像(Python 2.7,Pillow 2.4.0).
from PIL import Image large_size = (1920, 1200) im = Image.open("babu_980604.jpeg") image_w, image_h = im.size aspect_ratio = image_w / float(image_h) new_height = int(large_size[0] / aspect_ratio) if new_height < 1200: final_width = large_size[0] final_height = new_height else: final_width = int(aspect_ratio * large_size[1]) final_height = large_size[1] imaged = im.resize((final_width, final_height), Image.ANTIALIAS) imaged.show() imaged.save("out.jpg", quality=90)
这和你的代码之间的主要区别是它得到image_w
和image_h
从打开的图像,而不是直接get_image_dimensions(image)
,其实施不显示.
代码中的一些小问题:
你可以infile
在之前设置with open(...)
并在那里使用它.
final_size
未使用,可以删除,或以其他方式使用它im.resize()
.
base_width
可以替换为large_size[0]
,因为你也在large_size[1]
其他地方使用.
image
设置为requests.FILES['file']
但您也requests.FILES['file']
直接使用.你可以重用image
.
global random
可能不需要.