Маленько поправил, навел чуток красоты, надеюсь поможет кому нибудь еще.
from .utils import make_previews_img_models
class ImageProduct(models.Model):
image = models.ImageField(upload_to='image_products/original/', verbose_name='Файл')
product = models.ForeignKey(Product, verbose_name=u'связан с моделью', blank=True, null=True, related_name=u'images_product')
main_img = models.BooleanField("Обложка", default=None)
def save(self):
try:
img_obj = ImageModels.objects.get(id=self.id)
except:
img_obj = None
super(ImageProduct,self).save()
if not img_obj or img_obj.image != self.image:
make_previews_img_models(self, None)
Менеджер для обработки всех фото, в случае, если необходимо сделать новые превью сразу на все management/commands/make_prev_img.py
from django.core.management.base import BaseCommand, CommandError
from src.shop.models import ImageProduct, make_priviews_img_models
import os
from django.core.files.storage import default_storage
from PIL import Image, ImageOps, ImageEnhance
from src.settings import STATIC_ROOT, MEDIA_ROOT
import multiprocessing
class Command(BaseCommand):
help = u'make previews and big photos for images materials (all type - ldsp, sandblast, leather, upholstered)'
def handle(self, *args, **options):
make_priviews_img_models(None, ImageProduct.objects.all())
и, собственно, сам utils.py
import os
from django.core.files.storage import default_storage
from PIL import Image, ImageOps, ImageEnhance
from src.settings import STATIC_ROOT, MEDIA_ROOT
import multiprocessing
APPLY_WATERMARK = True;
PATCH_TO_WATERMARK = os.path.join(STATIC_ROOT, 'img/watermark_sport2000.png');
PATCH_TO_IMAGE_DIRECTORY = 'image_products'
ASPECT_RATIO_X = 1;
ASPECT_RATIO_Y = 1;
BACKGROUND_FOR_PREWIEW = 'white';
PREVIEW_SIZES = [
(1000,1000),
(350,350),
(200,200),
]
def reduce_opacity(im, opacity):
"""Делаем ватемарк прозрачным"""
assert 0 <= opacity <= 1
if im.mode != 'RGBA':
im = im.convert('RGBA')
else:
im = im.copy()
alpha = im.split()[3]
alpha = ImageEnhance.Brightness(alpha).enhance(opacity)
im.putalpha(alpha)
return im
def overlay_watermark_and_resize(obj_img_model):
"""Подгоняем изображение под пропорции (подкладываем белую подложку),
накладываем ватермарк и делаем превьюшки"""
img_origin = Image.open(obj_img_model.image)
if (img_origin.size[0]/ASPECT_RATIO_X) != (img_origin.size[1]/ASPECT_RATIO_Y):
if (img_origin.size[0]/ASPECT_RATIO_X) > (img_origin.size[1]/ASPECT_RATIO_Y):
underlay = (int(img_origin.size[0]), (int(img_origin.size[0]/ASPECT_RATIO_X)*ASPECT_RATIO_Y))
else:
underlay = (int((img_origin.size[1]/ASPECT_RATIO_Y)*ASPECT_RATIO_X), int(img_origin.size[1]))
underlay_background = Image.new('RGBA', underlay, BACKGROUND_FOR_PREWIEW)
underlay_background.paste( img_origin, (int((underlay[0] - img_origin.size[0]) / 2), int((underlay[1] - img_origin.size[1]) / 2)))
img_origin = underlay_background
img_name = str(obj_img_model.image).split('/')[-1]
if APPLY_WATERMARK:
watermark_origin = Image.open(PATCH_TO_WATERMARK)
wtm = reduce_opacity(watermark_origin, 1)
for preview_size in PREVIEW_SIZES:
img_preview = img_origin.copy()
img_preview.thumbnail(preview_size, Image.ANTIALIAS)
if APPLY_WATERMARK:
wtm_preview = wtm.copy()
wtm_preview.thumbnail(preview_size, Image.ANTIALIAS)
if img_preview.size != preview_size:
preview_background = Image.new('RGBA', preview_size, BACKGROUND_FOR_PREWIEW)
preview_background.paste(img_preview, (int((preview_background.size[0] - img_preview.size[0]) / 2), int((preview_background.size[1] - img_preview.size[1]) / 2)))
img_preview = preview_background
if APPLY_WATERMARK:
img_preview.paste(wtm_preview, (0,0), wtm_preview)
preview_path = os.path.join( PATCH_TO_IMAGE_DIRECTORY, '%sx%s' % (preview_size[0], preview_size[1]), img_name)
img_preview_file = default_storage.open(preview_path, 'w')
img_preview.save(img_preview_file, 'JPEG', optimize=True, progressive=True)
img_preview_file.close()
return None
def make_previews_img_models(img_obj=None, img_objects=None):
for preview_size in PREVIEW_SIZES:
if not os.path.exists(os.path.join(MEDIA_ROOT, '%s/%sx%s' % (PATCH_TO_IMAGE_DIRECTORY,preview_size[0], preview_size[1]))): os.makedirs(os.path.join(MEDIA_ROOT, '%s/%sx%s' % (PATCH_TO_IMAGE_DIRECTORY,preview_size[0], preview_size[1])))
if img_obj:
overlay_watermark_and_resize(img_obj)
if img_objects:
count = img_objects.count()
counter = 0
for img_obj in img_objects:
counter += 1
print(str(counter) + '/' + str(count) + ' - ' + str(img_obj.image))
p = multiprocessing.Process(target=overlay_watermark_and_resize, args=(img_obj))
p.start()
p.join(0.3)
return None
для подстановки превью в шаблонах использую шаблонный тег
<img src="{% replace_dir_in_img_url image_obj.url '/350x350/' %}" alt="">
@register.simple_tag
def replace_dir_in_img_url(img_url, dir_name):
'''
подменяем путь для превьюх, вместо original ставим папку с превью
'''
return img_url.replace('/original/', dir_name)
Если коментов где то не хватает - спрашивайте, добавлю.
Updated 10 June 2015, 14:49 by bloodlettinger.