~openerp-dev/openobject-server/trunk-res_bank_remove_footer-mdi

« back to all changes in this revision

Viewing changes to openerp/tools/image.py

  • Committer: Divyesh Makwana(Open ERP)
  • Date: 2012-08-08 04:30:38 UTC
  • mfrom: (4301.1.7 trunk)
  • Revision ID: mdi@tinyerp.com-20120808043038-abev1s0nvbluzqv2
[Merge] Merge with main server.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
##############################################################################
 
3
#
 
4
#    OpenERP, Open Source Management Solution
 
5
#    Copyright (C) 2012-today OpenERP s.a. (<http://openerp.com>).
 
6
#
 
7
#    This program is free software: you can redistribute it and/or modify
 
8
#    it under the terms of the GNU Affero General Public License as
 
9
#    published by the Free Software Foundation, either version 3 of the
 
10
#    License, or (at your option) any later version.
 
11
#
 
12
#    This program is distributed in the hope that it will be useful,
 
13
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
#    GNU Affero General Public License for more details.
 
16
#
 
17
#    You should have received a copy of the GNU Affero General Public License
 
18
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
#
 
20
##############################################################################
 
21
 
 
22
import io
 
23
from PIL import Image
 
24
import StringIO
 
25
 
 
26
# ----------------------------------------
 
27
# Image resizing
 
28
# ----------------------------------------
 
29
 
 
30
def image_resize_image(base64_source, size=(1024, 1024), encoding='base64', filetype='PNG', avoid_if_small=False):
 
31
    """ Function to resize an image. The image will be resized to the given
 
32
        size, while keeping the aspect ratios, and holes in the image will be
 
33
        filled with transparent background. The image will not be stretched if
 
34
        smaller than the expected size.
 
35
        Steps of the resizing:
 
36
        - if avoid_if_small: if both image sizes are smaller than the requested
 
37
          sizes, the original image is returned. This is used to avoid adding
 
38
          transparent content around images that we do not want to alter but
 
39
          just resize if too big. This is used for example when storing images
 
40
          in the 'image' field: we keep the original image, resized to a maximal
 
41
          size, without adding transparent content around it if smaller.
 
42
        - create a thumbnail of the source image through using the thumbnail
 
43
          function. Aspect ratios are preserved when using it. Note that if the
 
44
          source image is smaller than the expected size, it will not be
 
45
          extended, but filled to match the size.
 
46
        - create a transparent background that will hold the final
 
47
          image.
 
48
        - past the thumbnail on the transparent background and center
 
49
          it.
 
50
        
 
51
        :param base64_source: base64-encoded version of the source
 
52
            image
 
53
        :param size: tuple(height, width)
 
54
        :param encoding: the output encoding
 
55
        :param filetype: the output filetype
 
56
        :param avoid_if_small: do not resize if image height and width
 
57
            are smaller than the expected size.
 
58
    """
 
59
    image_stream = io.BytesIO(base64_source.decode(encoding))
 
60
    image = Image.open(image_stream)
 
61
    # check image size: do not create a thumbnail if avoiding smaller images
 
62
    if avoid_if_small and image.size[0] <= size[0] and image.size[1] <= size[1]:
 
63
        return base64_source
 
64
    # create a thumbnail: will resize and keep ratios
 
65
    image.thumbnail(size, Image.ANTIALIAS)
 
66
    # create a transparent image for background
 
67
    background = Image.new('RGBA', size, (255, 255, 255, 0))
 
68
    # past the resized image on the background
 
69
    background.paste(image, ((size[0] - image.size[0]) / 2, (size[1] - image.size[1]) / 2))
 
70
    # return an encoded image
 
71
    background_stream = StringIO.StringIO()
 
72
    background.save(background_stream, filetype)
 
73
    return background_stream.getvalue().encode(encoding)
 
74
 
 
75
def image_resize_image_big(base64_source, size=(1204, 1204), encoding='base64', filetype='PNG'):
 
76
    """ Wrapper on image_resize_image, to resize images larger than the standard
 
77
        'big' image size: 1024x1024px.
 
78
        :param base64_source: base64 encoded source image. If False,
 
79
            the function returns False.
 
80
    """
 
81
    if not base64_source:
 
82
        return False
 
83
    return image_resize_image(base64_source, size, encoding, filetype, True)
 
84
 
 
85
def image_resize_image_medium(base64_source, size=(180, 180), encoding='base64', filetype='PNG'):
 
86
    """ Wrapper on image_resize_image, to resize to the standard 'medium'
 
87
        image size: 180x180.
 
88
        :param base64_source: base64 encoded source image. If False,
 
89
            the function returns False.
 
90
    """
 
91
    if not base64_source:
 
92
        return False
 
93
    return image_resize_image(base64_source, size, encoding, filetype)
 
94
    
 
95
def image_resize_image_small(base64_source, size=(50, 50), encoding='base64', filetype='PNG'):
 
96
    """ Wrapper on image_resize_image, to resize to the standard 'small' image
 
97
        size: 50x50.
 
98
        :param base64_source: base64 encoded source image. If False,
 
99
            the function returns False.
 
100
    """
 
101
    if not base64_source:
 
102
        return False
 
103
    return image_resize_image(base64_source, size, encoding, filetype)
 
104
 
 
105
# ----------------------------------------
 
106
# Misc image tools
 
107
# ---------------------------------------
 
108
 
 
109
def image_get_resized_images(base64_source, return_big=False, return_medium=True, return_small=True,
 
110
    big_name='image', medium_name='image_medium', small_name='image_small'):
 
111
    """ Standard tool function that returns a dictionary containing the
 
112
        big, medium and small versions of the source image. This function
 
113
        is meant to be used for the methods of functional fields for
 
114
        models using images.
 
115
 
 
116
        Default parameters are given to be used for the getter of functional
 
117
        image fields,  for example with res.users or res.partner. It returns
 
118
        only image_medium and image_small values, to update those fields.
 
119
        
 
120
        :param base64_source: if set to False, other values are set to False
 
121
            also. The purpose is to be linked to the fields that hold images in
 
122
            OpenERP and that are binary fields.
 
123
        :param return_big: if set, return_dict contains the 'big_name' entry
 
124
        :param return_medium: if set, return_dict contains the 'medium_name' entry
 
125
        :param return_small: if set, return_dict contains the 'small_name' entry
 
126
        :param big_name: name related to the big version of the image;
 
127
            'image' by default.
 
128
        :param medium_name: name related to the medium version of the
 
129
            image; 'image_medium' by default.
 
130
        :param small_name: name related to the small version of the
 
131
            image; 'image_small' by default.
 
132
        :return return_dict: dictionary with resized images, depending on
 
133
            previous parameters.
 
134
    """
 
135
    return_dict = dict()
 
136
    if return_big: return_dict[big_name] = image_resize_image_big(base64_source)
 
137
    if return_medium: return_dict[medium_name] = image_resize_image_medium(base64_source)
 
138
    if return_small: return_dict[small_name] = image_resize_image_small(base64_source)
 
139
    return return_dict
 
 
b'\\ No newline at end of file'