Python中如何实现Django后台上传图片并生成部分区域缩略图在前台展示?
尺寸是固定的
Python中如何实现Django后台上传图片并生成部分区域缩略图在前台展示?
各大云存储不都支持图片裁剪缩略吗?
# settings.py 配置
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# models.py
from django.db import models
from PIL import Image
import os
class Article(models.Model):
title = models.CharField(max_length=100)
original_image = models.ImageField(upload_to='originals/')
thumbnail = models.ImageField(upload_to='thumbnails/', blank=True)
crop_x = models.IntegerField(default=0)
crop_y = models.IntegerField(default=0)
crop_width = models.IntegerField(default=100)
crop_height = models.IntegerField(default=100)
def generate_thumbnail(self):
if not self.original_image:
return
# 打开原始图片
img = Image.open(self.original_image.path)
# 确保裁剪区域在图片范围内
width, height = img.size
x = min(max(self.crop_x, 0), width - 1)
y = min(max(self.crop_y, 0), height - 1)
crop_w = min(self.crop_width, width - x)
crop_h = min(self.crop_height, height - y)
# 裁剪指定区域
cropped = img.crop((x, y, x + crop_w, y + crop_h))
# 生成缩略图(固定为100x100)
cropped.thumbnail((100, 100))
# 保存缩略图
thumb_path = f'thumbnails/{os.path.basename(self.original_image.name)}'
full_path = os.path.join(settings.MEDIA_ROOT, thumb_path)
cropped.save(full_path)
# 更新模型字段
self.thumbnail.name = thumb_path
self.save()
# admin.py
from django.contrib import admin
from .models import Article
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'original_image', 'thumbnail']
readonly_fields = ['thumbnail_preview']
def thumbnail_preview(self, obj):
if obj.thumbnail:
return format_html('<img src="{}" width="100" height="100" />', obj.thumbnail.url)
return "No thumbnail"
thumbnail_preview.short_description = 'Thumbnail Preview'
def save_model(self, request, obj, form, change):
super().save_model(request, obj, form, change)
obj.generate_thumbnail()
admin.site.register(Article, ArticleAdmin)
# template展示
"""
{% for article in articles %}
<div>
<h3>{{ article.title }}</h3>
<p>Original: <img src="{{ article.original_image.url }}" width="300"></p>
<p>Thumbnail: <img src="{{ article.thumbnail.url }}" width="100" height="100"></p>
</div>
{% endfor %}
"""
# views.py
from django.shortcuts import render
from .models import Article
def article_list(request):
articles = Article.objects.all()
return render(request, 'articles/list.html', {'articles': articles})
核心就这几步:1)用PIL的crop()裁剪指定区域;2)用thumbnail()调整尺寸;3)保存到media目录。记得安装Pillow库,配置好MEDIA设置。
建议用Pillow处理图片裁剪。
solr-thumbnail
印象中好像在 model 里可以定义 upload 图片之后做什么操作,也可能是别的地方
如果你问的是,如何自动选取最佳的一部分做缩略图,那这问题还有讨论的看头。
先说明,我对此没有经验。
最佳一般都在图片中间区域
我指的那种通过 CV 手段计算出图片最佳区域的。
https://blog.algorithmia.com/smart-thumbnail-image-cropping/
thum_width = models.PositiveIntegerField(default=50,verbose_name=‘缩略图宽度’)
thum_height = models.PositiveIntegerField(default=50,verbose_name=‘缩略图高度’)
img_thum = models.ImageField(upload_to=ThumPathAndRename(“product/thum/”),width_field=‘thum_width’,
height_field=‘thum_height’,null=True,blank=True,editable=True,verbose_name=‘缩略图’)
这样可以控制高度和宽度,代码很丑,可以改 CSS 呀

