枕头调整像素化图像 - Django/Pillow

 mobiledu2502917797 发布于 2023-01-12 17:56

我正在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)来处理我的图像.这种变化就像一个魅力!

1 个回答
  • 使用此代码,我得到了这个没有像素化的图像(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_wimage_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 可能不需要.

    2023-01-12 17:58 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有