~ubuntu-branches/debian/squeeze/python-imaging/squeeze

« back to all changes in this revision

Viewing changes to PIL/Image.py

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-11-20 19:22:59 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20091120192259-n3iy0f17n5akogom
Tags: 1.1.7-1
New upstream version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#
2
2
# The Python Imaging Library.
3
 
# $Id: Image.py 2933 2006-12-03 12:08:22Z fredrik $
 
3
# $Id$
4
4
#
5
5
# the Image class wrapper
6
6
#
16
16
# 2003-05-10 fl   PIL release 1.1.4
17
17
# 2005-03-28 fl   PIL release 1.1.5
18
18
# 2006-12-02 fl   PIL release 1.1.6
 
19
# 2009-11-15 fl   PIL release 1.1.7
19
20
#
20
 
# Copyright (c) 1997-2006 by Secret Labs AB.  All rights reserved.
21
 
# Copyright (c) 1995-2006 by Fredrik Lundh.
 
21
# Copyright (c) 1997-2009 by Secret Labs AB.  All rights reserved.
 
22
# Copyright (c) 1995-2009 by Fredrik Lundh.
22
23
#
23
24
# See the README file for information on usage and redistribution.
24
25
#
25
26
 
26
 
VERSION = "1.1.6"
 
27
VERSION = "1.1.7"
27
28
 
28
29
try:
29
30
    import warnings
68
69
import ImageMode
69
70
import ImagePalette
70
71
 
71
 
import os, stat, string, sys
 
72
import os, string, sys
72
73
 
73
74
# type stuff
74
75
from types import IntType, StringType, TupleType
181
182
    "CMYK": ("RGB", "L", ("C", "M", "Y", "K")),
182
183
    "YCbCr": ("RGB", "L", ("Y", "Cb", "Cr")),
183
184
 
184
 
    # Experimental modes include I;16, I;16B, RGBa, BGR;15,
185
 
    # and BGR;24.  Use these modes only if you know exactly
186
 
    # what you're doing...
 
185
    # Experimental modes include I;16, I;16L, I;16B, RGBa, BGR;15, and
 
186
    # BGR;24.  Use these modes only if you know exactly what you're
 
187
    # doing...
187
188
 
188
189
}
189
190
 
190
 
if sys.byteorder == 'little':
 
191
try:
 
192
    byteorder = sys.byteorder
 
193
except AttributeError:
 
194
    import struct
 
195
    if struct.unpack("h", "\0\1")[0] == 1:
 
196
        byteorder = "big"
 
197
    else:
 
198
        byteorder = "little"
 
199
 
 
200
if byteorder == 'little':
191
201
    _ENDIAN = '<'
192
202
else:
193
203
    _ENDIAN = '>'
194
204
 
195
205
_MODE_CONV = {
196
206
    # official modes
197
 
    "1": ('|b1', None),
 
207
    "1": ('|b1', None), # broken
198
208
    "L": ('|u1', None),
199
 
    "I": ('%si4' % _ENDIAN, None), # FIXME: is this correct?
200
 
    "I;16": ('%si2' % _ENDIAN, None),
201
 
    "F": ('%sf4' % _ENDIAN, None), # FIXME: is this correct?
 
209
    "I": (_ENDIAN + 'i4', None),
 
210
    "F": (_ENDIAN + 'f4', None),
202
211
    "P": ('|u1', None),
203
212
    "RGB": ('|u1', 3),
204
213
    "RGBX": ('|u1', 4),
208
217
}
209
218
 
210
219
def _conv_type_shape(im):
211
 
    shape = im.size[::-1]
 
220
    shape = im.size[1], im.size[0]
212
221
    typ, extra = _MODE_CONV[im.mode]
213
222
    if extra is None:
214
223
        return shape, typ
221
230
 
222
231
# raw modes that may be memory mapped.  NOTE: if you change this, you
223
232
# may have to modify the stride calculation in map.c too!
224
 
_MAPMODES = ("L", "P", "RGBX", "RGBA", "CMYK", "I;16", "I;16B")
 
233
_MAPMODES = ("L", "P", "RGBX", "RGBA", "CMYK", "I;16", "I;16L", "I;16B")
225
234
 
226
235
##
227
236
# Gets the "base" mode for given mode.  This function returns "L" for
321
330
 
322
331
    global _initialized
323
332
    if _initialized >= 2:
324
 
        return
 
333
        return 0
325
334
 
326
335
    visited = {}
327
336
 
354
363
 
355
364
    if OPEN or SAVE:
356
365
        _initialized = 2
357
 
 
 
366
        return 1
358
367
 
359
368
# --------------------------------------------------------------------
360
369
# Codec factories (used by tostring/fromstring and ImageFile.load)
438
447
    format_description = None
439
448
 
440
449
    def __init__(self):
 
450
        # FIXME: take "new" parameters / other image?
 
451
        # FIXME: turn mode and size into delegating properties?
441
452
        self.im = None
442
453
        self.mode = ""
443
454
        self.size = (0, 0)
482
493
            self.save(file, format)
483
494
        return file
484
495
 
 
496
    def __repr__(self):
 
497
        return "<%s.%s image mode=%s size=%dx%d at 0x%X>" % (
 
498
            self.__class__.__module__, self.__class__.__name__,
 
499
            self.mode, self.size[0], self.size[1],
 
500
            id(self)
 
501
            )
 
502
 
485
503
    def __getattr__(self, name):
486
504
        if name == "__array_interface__":
487
505
            # numpy array interface support
611
629
        "Verify file contents."
612
630
        pass
613
631
 
614
 
 
615
632
    ##
616
633
    # Returns a converted copy of this image. For the "P" mode, this
617
634
    # method translates pixels through the palette.  If mode is
630
647
    # "1"), all non-zero values are set to 255 (white). To use other
631
648
    # thresholds, use the {@link #Image.point} method.
632
649
    #
633
 
    # @def convert(mode, matrix=None)
 
650
    # @def convert(mode, matrix=None, **options)
634
651
    # @param mode The requested mode.
635
652
    # @param matrix An optional conversion matrix.  If given, this
636
653
    #    should be 4- or 16-tuple containing floating point values.
 
654
    # @param options Additional options, given as keyword arguments.
 
655
    # @keyparam dither Dithering method, used when converting from
 
656
    #    mode "RGB" to "P".
 
657
    #    Available methods are NONE or FLOYDSTEINBERG (default).
 
658
    # @keyparam palette Palette to use when converting from mode "RGB"
 
659
    #    to "P".  Available palettes are WEB or ADAPTIVE.
 
660
    # @keyparam colors Number of colors to use for the ADAPTIVE palette.
 
661
    #    Defaults to 256.
637
662
    # @return An Image object.
638
663
 
639
664
    def convert(self, mode=None, data=None, dither=None,
779
804
 
780
805
        self.load()
781
806
 
782
 
        from ImageFilter import Filter
783
 
        if not isinstance(filter, Filter):
 
807
        if callable(filter):
784
808
            filter = filter()
 
809
        if not hasattr(filter, "filter"):
 
810
            raise TypeError("filter argument should be ImageFilter.Filter instance or class")
785
811
 
786
812
        if self.im.bands == 1:
787
813
            return self._new(filter.filter(self.im))
1094
1120
 
1095
1121
        self.load()
1096
1122
 
 
1123
        if isinstance(lut, ImagePointHandler):
 
1124
            return lut.point(self)
 
1125
 
1097
1126
        if not isSequenceType(lut):
1098
1127
            # if it isn't a list, it should be a function
1099
1128
            if self.mode in ("I", "I;16", "F"):
1199
1228
    def putpalette(self, data, rawmode="RGB"):
1200
1229
        "Put palette data into an image."
1201
1230
 
1202
 
        self.load()
1203
1231
        if self.mode not in ("L", "P"):
1204
1232
            raise ValueError("illegal image mode")
1205
 
        if not isStringType(data):
1206
 
            data = string.join(map(chr, data), "")
 
1233
        self.load()
 
1234
        if isinstance(data, ImagePalette.ImagePalette):
 
1235
            palette = ImagePalette.raw(data.rawmode, data.palette)
 
1236
        else:
 
1237
            if not isStringType(data):
 
1238
                data = string.join(map(chr, data), "")
 
1239
            palette = ImagePalette.raw(rawmode, data)
1207
1240
        self.mode = "P"
1208
 
        self.palette = ImagePalette.raw(rawmode, data)
 
1241
        self.palette = palette
1209
1242
        self.palette.mode = "RGB"
1210
1243
        self.load() # install new palette
1211
1244
 
1318
1351
            matrix[2] = self.size[0] / 2.0 - x
1319
1352
            matrix[5] = self.size[1] / 2.0 - y
1320
1353
 
1321
 
            return self.transform((w, h), AFFINE, matrix)
 
1354
            return self.transform((w, h), AFFINE, matrix, resample)
1322
1355
 
1323
1356
        if resample not in (NEAREST, BILINEAR, BICUBIC):
1324
1357
            raise ValueError("unknown resampling filter")
1447
1480
    def show(self, title=None, command=None):
1448
1481
        "Display image (for debug purposes only)"
1449
1482
 
1450
 
        _showxv(self, title, command)
 
1483
        _show(self, title=title, command=command)
1451
1484
 
1452
1485
    ##
1453
1486
    # Split this image into individual bands. This method returns a
1461
1494
    def split(self):
1462
1495
        "Split image into bands"
1463
1496
 
1464
 
        ims = []
1465
 
        self.load()
1466
 
        for i in range(self.im.bands):
1467
 
            ims.append(self._new(self.im.getband(i)))
 
1497
        if self.im.bands == 1:
 
1498
            ims = [self.copy()]
 
1499
        else:
 
1500
            ims = []
 
1501
            self.load()
 
1502
            for i in range(self.im.bands):
 
1503
                ims.append(self._new(self.im.getband(i)))
1468
1504
        return tuple(ims)
1469
1505
 
1470
1506
    ##
1563
1599
    def transform(self, size, method, data=None, resample=NEAREST, fill=1):
1564
1600
        "Transform image"
1565
1601
 
1566
 
        import ImageTransform
1567
 
        if isinstance(method, ImageTransform.Transform):
 
1602
        if isinstance(method, ImageTransformHandler):
 
1603
            return method.transform(size, self, resample=resample, fill=fill)
 
1604
        if hasattr(method, "getdata"):
 
1605
            # compatibility w. old-style transform objects
1568
1606
            method, data = method.getdata()
1569
1607
        if data is None:
1570
1608
            raise ValueError("missing method data")
1668
1706
            self.im = self.im.crop(self.__crop)
1669
1707
            self.__crop = None
1670
1708
 
 
1709
        if self.im:
 
1710
            return self.im.pixel_access(self.readonly)
 
1711
 
1671
1712
        # FIXME: future versions should optimize crop/paste
1672
1713
        # sequences!
1673
1714
 
1674
1715
# --------------------------------------------------------------------
 
1716
# Abstract handlers.
 
1717
 
 
1718
class ImagePointHandler:
 
1719
    # used as a mixin by point transforms (for use with im.point)
 
1720
    pass
 
1721
 
 
1722
class ImageTransformHandler:
 
1723
    # used as a mixin by geometry transforms (for use with im.transform)
 
1724
    pass
 
1725
 
 
1726
# --------------------------------------------------------------------
1675
1727
# Factories
1676
1728
 
1677
1729
#
1803
1855
            im.readonly = 1
1804
1856
            return im
1805
1857
 
1806
 
    return apply(fromstring, (mode, size, data, decoder_name, args))
 
1858
    return fromstring(mode, size, data, decoder_name, args)
1807
1859
 
1808
1860
 
1809
1861
##
1810
 
# (New in 1.1.6) Create an image memory from an object exporting
 
1862
# (New in 1.1.6) Creates an image memory from an object exporting
1811
1863
# the array interface (using the buffer protocol).
1812
1864
#
1813
1865
# If obj is not contiguous, then the tostring method is called
1826
1878
    except KeyError:
1827
1879
        strides = None
1828
1880
    if mode is None:
1829
 
        typestr = arr['typestr']
1830
 
        if not (typestr[0] == '|' or typestr[0] == _ENDIAN or
1831
 
                typestr[1:] not in ['u1', 'b1', 'i4', 'f4']):
1832
 
            raise TypeError("cannot handle data-type")
1833
 
        typestr = typestr[:2]
1834
 
        if typestr == 'i4':
1835
 
            mode = 'I'
1836
 
        elif typestr == 'f4':
1837
 
            mode = 'F'
1838
 
        elif typestr == 'b1':
1839
 
            mode = '1'
1840
 
        elif ndim == 2:
1841
 
            mode = 'L'
1842
 
        elif ndim == 3:
1843
 
            mode = 'RGB'
1844
 
        elif ndim == 4:
1845
 
            mode = 'RGBA'
1846
 
        else:
1847
 
            raise TypeError("Do not understand data.")
1848
 
    ndmax = 4
1849
 
    bad_dims=0
1850
 
    if mode in ['1','L','I','P','F']:
 
1881
        try:
 
1882
            typekey = (1, 1) + shape[2:], arr['typestr']
 
1883
            mode, rawmode = _fromarray_typemap[typekey]
 
1884
        except KeyError:
 
1885
            # print typekey
 
1886
            raise TypeError("Cannot handle this data type")
 
1887
    else:
 
1888
        rawmode = mode
 
1889
    if mode in ["1", "L", "I", "P", "F"]:
1851
1890
        ndmax = 2
1852
 
    elif mode == 'RGB':
 
1891
    elif mode == "RGB":
1853
1892
        ndmax = 3
 
1893
    else:
 
1894
        ndmax = 4
1854
1895
    if ndim > ndmax:
1855
1896
        raise ValueError("Too many dimensions.")
1856
1897
 
1857
 
    size = shape[:2][::-1]
 
1898
    size = shape[1], shape[0]
1858
1899
    if strides is not None:
1859
1900
        obj = obj.tostring()
1860
1901
 
1861
 
    return frombuffer(mode, size, obj, "raw", mode, 0, 1)
 
1902
    return frombuffer(mode, size, obj, "raw", rawmode, 0, 1)
 
1903
 
 
1904
_fromarray_typemap = {
 
1905
    # (shape, typestr) => mode, rawmode
 
1906
    # first two members of shape are set to one
 
1907
    # ((1, 1), "|b1"): ("1", "1"), # broken
 
1908
    ((1, 1), "|u1"): ("L", "L"),
 
1909
    ((1, 1), "|i1"): ("I", "I;8"),
 
1910
    ((1, 1), "<i2"): ("I", "I;16"),
 
1911
    ((1, 1), ">i2"): ("I", "I;16B"),
 
1912
    ((1, 1), "<i4"): ("I", "I;32"),
 
1913
    ((1, 1), ">i4"): ("I", "I;32B"),
 
1914
    ((1, 1), "<f4"): ("F", "F;32F"),
 
1915
    ((1, 1), ">f4"): ("F", "F;32BF"),
 
1916
    ((1, 1), "<f8"): ("F", "F;64F"),
 
1917
    ((1, 1), ">f8"): ("F", "F;64BF"),
 
1918
    ((1, 1, 3), "|u1"): ("RGB", "RGB"),
 
1919
    ((1, 1, 4), "|u1"): ("RGBA", "RGBA"),
 
1920
    }
 
1921
 
 
1922
# shortcuts
 
1923
_fromarray_typemap[((1, 1), _ENDIAN + "i4")] = ("I", "I")
 
1924
_fromarray_typemap[((1, 1), _ENDIAN + "f4")] = ("F", "F")
1862
1925
 
1863
1926
##
1864
1927
# Opens and identifies the given image file.
1903
1966
        except (SyntaxError, IndexError, TypeError):
1904
1967
            pass
1905
1968
 
1906
 
    init()
 
1969
    if init():
1907
1970
 
1908
 
    for i in ID:
1909
 
        try:
1910
 
            factory, accept = OPEN[i]
1911
 
            if not accept or accept(prefix):
1912
 
                fp.seek(0)
1913
 
                return factory(fp, filename)
1914
 
        except (SyntaxError, IndexError, TypeError):
1915
 
            pass
 
1971
        for i in ID:
 
1972
            try:
 
1973
                factory, accept = OPEN[i]
 
1974
                if not accept or accept(prefix):
 
1975
                    fp.seek(0)
 
1976
                    return factory(fp, filename)
 
1977
            except (SyntaxError, IndexError, TypeError):
 
1978
                pass
1916
1979
 
1917
1980
    raise IOError("cannot identify image file")
1918
1981
 
2053
2116
 
2054
2117
 
2055
2118
# --------------------------------------------------------------------
2056
 
# Simple display support
2057
 
 
2058
 
def _showxv(image, title=None, command=None):
2059
 
 
2060
 
    if os.name == "nt":
2061
 
        format = "BMP"
2062
 
    elif sys.platform == "darwin":
2063
 
        format = "JPEG"
2064
 
        if not command:
2065
 
            command = "open -a /Applications/Preview.app"
2066
 
    else:
2067
 
        format = None
2068
 
        if not command:
2069
 
            for cmd in ["eog", "gqview", "gwenview", "xv"]:
2070
 
                if _iscommand(cmd):
2071
 
                    command = cmd
2072
 
                    break
2073
 
            if not command:
2074
 
                # raise OSError, "no image viewer found"
2075
 
                print "no image viewer found"
2076
 
            if command in ("xv") and title:
2077
 
                command = command + " -name \"%s\"" % title
2078
 
 
2079
 
    if image.mode == "I;16":
2080
 
        # @PIL88 @PIL101
2081
 
        # "I;16" isn't an 'official' mode, but we still want to
2082
 
        # provide a simple way to show 16-bit images.
2083
 
        base = "L"
2084
 
    else:
2085
 
        base = getmodebase(image.mode)
2086
 
    if base != image.mode and image.mode != "1":
2087
 
        file = image.convert(base)._dump(format=format)
2088
 
    else:
2089
 
        file = image._dump(format=format)
2090
 
 
2091
 
    if os.name == "nt":
2092
 
        command = "start /wait %s && del /f %s" % (file, file)
2093
 
    elif sys.platform == "darwin":
2094
 
        # on darwin open returns immediately resulting in the temp
2095
 
        # file removal while app is opening
2096
 
        command = "(%s %s; sleep 20; rm -f %s)&" % (command, file, file)
2097
 
    else:
2098
 
        command = "(%s %s; rm -f %s)&" % (command, file, file)
2099
 
 
2100
 
    os.system(command)
2101
 
 
2102
 
def _isexecutable(cmd):
2103
 
    if os.path.isfile(cmd):
2104
 
        mode = os.stat(cmd)[stat.ST_MODE]
2105
 
        if mode & stat.S_IXUSR or mode & stat.S_IXGRP or mode & stat.S_IXOTH:
2106
 
            return True
2107
 
    return False
2108
 
 
2109
 
def _iscommand(cmd):
2110
 
    """Return True if cmd is executable or can be found on the executable
2111
 
    search path."""
2112
 
    if _isexecutable(cmd):
2113
 
        return True
2114
 
    path = os.environ.get("PATH")
2115
 
    if not path:
2116
 
        return False
2117
 
    for d in path.split(os.pathsep):
2118
 
        exe = os.path.join(d, cmd)
2119
 
        if _isexecutable(exe):
2120
 
            return True
2121
 
    return False
 
2119
# Simple display support.  User code may override this.
 
2120
 
 
2121
def _show(image, **options):
 
2122
    # override me, as necessary
 
2123
    apply(_showxv, (image,), options)
 
2124
 
 
2125
def _showxv(image, title=None, **options):
 
2126
    import ImageShow
 
2127
    apply(ImageShow.show, (image, title), options)