degal/thumbnail.py
author Tero Marttila <terom@fixme.fi>
Mon, 15 Jun 2009 00:29:43 +0300
changeset 123 31c4a328ef96
parent 122 292aaba6d6ec
child 125 74f135774567
permissions -rw-r--r--
move the uncache-del's from commands.main to Image.cleanup, and call it after rendering each image's thumbs
85
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     1
"""
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     2
    State for thumbnails; derivates of Images
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     3
"""
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     4
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     5
import filesystem
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     6
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     7
import PIL.Image
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     8
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
     9
class Thumbnail (filesystem.File) :
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    10
    """
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    11
        A Thumbnail is a derivate of an Image, usually resized to some other size.
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    12
    """
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    13
115
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    14
    def __init__ (self, image, subdir, target_size) :
85
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    15
        """
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    16
            Initialize to link against the given `image`.
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    17
            
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    18
            `subdir` specifies the directory to store this thumbnail in.
115
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    19
            `target_size` determines the target resolution of the output thumbnail.
85
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    20
        """
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    21
95
3b00bd676fc9 fix Thumbnail.stale/File.older_than behaviour
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
    22
        # our file path, image name inside of the given subdir
3b00bd676fc9 fix Thumbnail.stale/File.older_than behaviour
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
    23
        super(Thumbnail, self).__init__(subdir, image.fsname)
85
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    24
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    25
        # store
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    26
        self.image = image
115
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    27
        self.target_size = target_size
85
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    28
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    29
    def stale (self) :
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    30
        """
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    31
            Tests if this thumbnail is stale
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    32
        """
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    33
        
95
3b00bd676fc9 fix Thumbnail.stale/File.older_than behaviour
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
    34
        if self.image.older_than(self) :
3b00bd676fc9 fix Thumbnail.stale/File.older_than behaviour
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
    35
            # both exist and this is newer
3b00bd676fc9 fix Thumbnail.stale/File.older_than behaviour
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
    36
            return False
3b00bd676fc9 fix Thumbnail.stale/File.older_than behaviour
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
    37
        
3b00bd676fc9 fix Thumbnail.stale/File.older_than behaviour
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
    38
        else :
3b00bd676fc9 fix Thumbnail.stale/File.older_than behaviour
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
    39
            # this thumb doesn't exist or is older
3b00bd676fc9 fix Thumbnail.stale/File.older_than behaviour
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
    40
            return True
115
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    41
    
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    42
    @property
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    43
    def size (self) :
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    44
        """
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    45
            Compute the *real* size of this thumbnail, from the image's actual size and our target size.
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    46
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    47
            Preserves the aspect ratio etc.
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    48
        """
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    49
        
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    50
        # real image size
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    51
        img_width, img_height = self.image.img_size
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    52
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    53
        # target size
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    54
        thumb_width, thumb_height = self.target_size
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    55
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    56
        # calc new size, preserving aspect ratio
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    57
        if img_width > thumb_width : 
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    58
            height = max(img_height * thumb_width / img_width, 1)
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    59
            width = thumb_width
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    60
        
116
2d3721b9ffd0 fix Thumbnail.size logic, s/if/elif/
Tero Marttila <terom@fixme.fi>
parents: 115
diff changeset
    61
        elif img_height > thumb_height :
115
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    62
            width = max(img_width * thumb_height / img_height, 1)
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    63
            height = thumb_height
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    64
        
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    65
        return width, height 
123
31c4a328ef96 move the uncache-del's from commands.main to Image.cleanup, and call it after rendering each image's thumbs
Tero Marttila <terom@fixme.fi>
parents: 122
diff changeset
    66
   
31c4a328ef96 move the uncache-del's from commands.main to Image.cleanup, and call it after rendering each image's thumbs
Tero Marttila <terom@fixme.fi>
parents: 122
diff changeset
    67
    ## operations
122
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    68
    def resize (self, img) :
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    69
        """
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    70
            Resize the give image as needed.
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    71
        """
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    72
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    73
        return img.resize(self.size, resample=PIL.Image.ANTIALIAS)
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    74
    
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    75
    def auto_orient (self, img, orient_info) :
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    76
        """
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    77
            Automatically orient the image using the given orientation info.
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    78
        """
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    79
        
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    80
        # unpack
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    81
        mirroring, rotation = orient_info
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    82
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    83
        if mirroring :
123
31c4a328ef96 move the uncache-del's from commands.main to Image.cleanup, and call it after rendering each image's thumbs
Tero Marttila <terom@fixme.fi>
parents: 122
diff changeset
    84
            # XXX: does anyone actually use this?
122
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    85
            pass
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    86
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    87
        if rotation :
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    88
            # since these are in steps of 90 degrees, it should keep the right size
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    89
            # but gah, PIL wants these as counter-clockwise!
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    90
            img = img.rotate(360 - rotation)
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    91
        
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    92
        # ok
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
    93
        return img
85
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    94
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    95
    def update (self) :
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    96
        """
115
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
    97
            Render new output thumbnail.
85
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    98
        """
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
    99
122
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
   100
        # start with origional image
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
   101
        img = self.image.img
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
   102
115
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   103
        # create resized copy of main image, using our size
122
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
   104
        img = self.resize(img)
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
   105
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
   106
        # got orientation info?
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
   107
        if self.image.orientation :
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
   108
            img = self.auto_orient(img, self.image.orientation)
85
7da934333469 move thumbnail rendering from render.py to thumbnail.py, and implement staleness checking for Images, plus index_images for Folder
Tero Marttila <terom@fixme.fi>
parents:
diff changeset
   109
115
d5aa320697df rename Image.pil_image -> Image.img, and shave off ~30ms per image by using Image.resize instead of Image.copy/Image.thumbnail
Tero Marttila <terom@fixme.fi>
parents: 95
diff changeset
   110
        # write it out
122
292aaba6d6ec auto-orientation, although no mirroring support yet
Tero Marttila <terom@fixme.fi>
parents: 116
diff changeset
   111
        img.save(self.path)
95
3b00bd676fc9 fix Thumbnail.stale/File.older_than behaviour
Tero Marttila <terom@fixme.fi>
parents: 85
diff changeset
   112