mirror of
https://github.com/NaN-tic/trytond-product_images.git
synced 2023-12-14 03:23:04 +01:00
801f4e748d
because product_attachments add new field: thumb
109 lines
4.2 KiB
Python
109 lines
4.2 KiB
Python
# The COPYRIGHT file at the top level of this repository contains the full
|
|
# copyright notices and license terms.
|
|
from trytond.model import fields
|
|
from trytond.pool import Pool, PoolMeta
|
|
from trytond.config import config as config_
|
|
from PIL import Image
|
|
import io
|
|
|
|
__all__ = ['Attachment', 'Template']
|
|
THUMB_QUALITY = config_.getint('product', 'thumb_quality', default=85)
|
|
THUMB_CROP = config_.get('product', 'thumb_crop', default='')
|
|
THUMB_WIDTH = config_.getint('product', 'thumb_width', default=600)
|
|
THUMB_HEIGHT = config_.getint('product', 'thumb_height', default=600)
|
|
|
|
class Attachment(metaclass=PoolMeta):
|
|
__name__ = 'ir.attachment'
|
|
product_image = fields.Boolean('Product Image')
|
|
|
|
|
|
class Template(metaclass=PoolMeta):
|
|
__name__ = 'product.template'
|
|
images = fields.One2Many('ir.attachment', 'resource', 'Images',
|
|
filter=[
|
|
('product_image', '=', True),
|
|
])
|
|
image = fields.Function(fields.Many2One('ir.attachment', 'Image'),
|
|
'get_image')
|
|
image_thumb = fields.Function(fields.Binary('Image Thumb',
|
|
filename='image_thumb_filename'), 'get_image_thumb')
|
|
image_thumb_filename = fields.Function(fields.Char("File Name Image Thumb"),
|
|
'get_image_thumb_filename')
|
|
|
|
@classmethod
|
|
def get_image(cls, records, names):
|
|
res = {n: {r.id: None for r in records} for n in names}
|
|
for name in names:
|
|
for record in records:
|
|
if record.images:
|
|
res[name][record.id] = record.images[0].id
|
|
return res
|
|
|
|
@staticmethod
|
|
def create_thumb(data, image_format, crop=THUMB_CROP,
|
|
width=THUMB_WIDTH, height=THUMB_HEIGHT, quality=THUMB_QUALITY):
|
|
size = (width, height)
|
|
try:
|
|
img = Image.open(io.BytesIO(data))
|
|
except:
|
|
return
|
|
|
|
if crop:
|
|
img_ratio = img.size[0] / float(img.size[1])
|
|
ratio = size[0] / float(size[1])
|
|
|
|
# Scaled/cropped vertically or horizontally depending on the ratio
|
|
if ratio > img_ratio:
|
|
img = img.resize((size[0], size[0] * img.size[1] / img.size[0]),
|
|
Image.ANTIALIAS)
|
|
# Crop in the top, middle or bottom
|
|
if crop == 'top':
|
|
box = (0, 0, img.size[0], size[1])
|
|
elif crop == 'bottom':
|
|
box = (0, img.size[1] - size[1], img.size[0], img.size[1])
|
|
else :
|
|
box = (0, (img.size[1] - size[1]) / 2, img.size[0],
|
|
(img.size[1] + size[1]) / 2)
|
|
img = img.crop(box)
|
|
elif ratio < img_ratio:
|
|
img = img.resize((size[1] * img.size[0] / img.size[1], size[1]),
|
|
Image.ANTIALIAS)
|
|
# Crop in the top, middle or bottom
|
|
if crop == 'top':
|
|
box = (0, 0, size[0], img.size[1])
|
|
elif crop == 'bottom':
|
|
box = (img.size[0] - size[0], 0, img.size[0], img.size[1])
|
|
else :
|
|
box = ((img.size[0] - size[0]) / 2, 0,
|
|
(img.size[0] + size[0]) / 2, img.size[1])
|
|
img.crop(box)
|
|
else:
|
|
img.thumbnail(size)
|
|
|
|
imgByteArr = io.BytesIO()
|
|
img.save(imgByteArr, image_format, quality=quality)
|
|
return bytearray(imgByteArr.getvalue())
|
|
|
|
@classmethod
|
|
def get_image_thumb(cls, records, names):
|
|
res = {n: {r.id: None for r in records} for n in names}
|
|
for name in names:
|
|
for record in records:
|
|
if record.image and record.image.data:
|
|
image_format, = record.image.name.split('.')[-1:]
|
|
imgformat = (image_format.lower() if image_format.lower()
|
|
in {'png', 'jpeg'} else 'jpeg')
|
|
res[name][record.id] = cls.create_thumb(record.image.data, imgformat)
|
|
return res
|
|
|
|
def get_image_thumb_filename(self, name):
|
|
return self.image.name if self.image else None
|
|
|
|
@classmethod
|
|
def delete(cls, templates):
|
|
pool = Pool()
|
|
Attachment = pool.get('ir.attachment')
|
|
|
|
attachments = [a for t in templates for a in t.images]
|
|
Attachment.delete(attachments)
|
|
super(Template, cls).delete(templates)
|