thirdparty/google_appengine/google/appengine/api/images/__init__.py
author Pawel Solyga <Pawel.Solyga@gmail.com>
Thu, 21 May 2009 14:44:41 +0200
changeset 2331 91379f6b8fcb
parent 2273 e4cb9c53db3e
child 3031 7678f72140e6
permissions -rwxr-xr-x
Add sorting of student projects on organization home page. List of student projects on organization home page is now sorted in alphabetical order by student name. Fixes issue 613.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     1
#!/usr/bin/env python
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     2
#
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     3
# Copyright 2007 Google Inc.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     4
#
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     5
# Licensed under the Apache License, Version 2.0 (the "License");
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     6
# you may not use this file except in compliance with the License.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     7
# You may obtain a copy of the License at
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     8
#
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
     9
#     http://www.apache.org/licenses/LICENSE-2.0
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    10
#
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    11
# Unless required by applicable law or agreed to in writing, software
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    12
# distributed under the License is distributed on an "AS IS" BASIS,
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    14
# See the License for the specific language governing permissions and
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    15
# limitations under the License.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    16
#
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    17
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    18
"""Image manipulation API.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    19
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    20
Classes defined in this module:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    21
  Image: class used to encapsulate image information and transformations for
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    22
    that image.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    23
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    24
    The current manipulations that are available are resize, rotate,
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    25
    horizontal_flip, vertical_flip, crop and im_feeling_lucky.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    26
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    27
    It should be noted that each transform can only be called once per image
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    28
    per execute_transforms() call.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    29
"""
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    30
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    31
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    32
828
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
    33
import struct
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
    34
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    35
from google.appengine.api import apiproxy_stub_map
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    36
from google.appengine.api.images import images_service_pb
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    37
from google.appengine.runtime import apiproxy_errors
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    38
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    39
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    40
JPEG = images_service_pb.OutputSettings.JPEG
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    41
PNG = images_service_pb.OutputSettings.PNG
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    42
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    43
OUTPUT_ENCODING_TYPES = frozenset([JPEG, PNG])
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    44
2273
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    45
TOP_LEFT = images_service_pb.CompositeImageOptions.TOP_LEFT
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    46
TOP_CENTER = images_service_pb.CompositeImageOptions.TOP
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    47
TOP_RIGHT = images_service_pb.CompositeImageOptions.TOP_RIGHT
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    48
CENTER_LEFT = images_service_pb.CompositeImageOptions.LEFT
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    49
CENTER_CENTER = images_service_pb.CompositeImageOptions.CENTER
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    50
CENTER_RIGHT = images_service_pb.CompositeImageOptions.RIGHT
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    51
BOTTOM_LEFT = images_service_pb.CompositeImageOptions.BOTTOM_LEFT
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    52
BOTTOM_CENTER = images_service_pb.CompositeImageOptions.BOTTOM
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    53
BOTTOM_RIGHT = images_service_pb.CompositeImageOptions.BOTTOM_RIGHT
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    54
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    55
ANCHOR_TYPES = frozenset([TOP_LEFT, TOP_CENTER, TOP_RIGHT, CENTER_LEFT,
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    56
                          CENTER_CENTER, CENTER_RIGHT, BOTTOM_LEFT,
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    57
                          BOTTOM_CENTER, BOTTOM_RIGHT])
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    58
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
    59
MAX_TRANSFORMS_PER_REQUEST = 10
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
    60
2273
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    61
MAX_COMPOSITES_PER_REQUEST = 16
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
    62
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    63
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    64
class Error(Exception):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    65
  """Base error class for this module."""
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    66
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    67
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    68
class TransformationError(Error):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    69
  """Error while attempting to transform the image."""
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    70
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    71
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    72
class BadRequestError(Error):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    73
  """The parameters given had something wrong with them."""
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    74
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    75
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    76
class NotImageError(Error):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    77
  """The image data given is not recognizable as an image."""
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    78
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    79
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    80
class BadImageError(Error):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    81
  """The image data given is corrupt."""
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    82
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    83
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    84
class LargeImageError(Error):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    85
  """The image data given is too large to process."""
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    86
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    87
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    88
class Image(object):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    89
  """Image object to manipulate."""
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    90
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    91
  def __init__(self, image_data):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    92
    """Constructor.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    93
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    94
    Args:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    95
      image_data: str, image data in string form.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    96
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    97
    Raises:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    98
      NotImageError if the given data is empty.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
    99
    """
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   100
    if not image_data:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   101
      raise NotImageError("Empty image data.")
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   102
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   103
    self._image_data = image_data
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   104
    self._transforms = []
828
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   105
    self._width = None
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   106
    self._height = None
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   107
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   108
  def _check_transform_limits(self):
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   109
    """Ensure some simple limits on the number of transforms allowed.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   110
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   111
    Raises:
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   112
      BadRequestError if MAX_TRANSFORMS_PER_REQUEST transforms have already been
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   113
      requested for this image
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   114
    """
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   115
    if len(self._transforms) >= MAX_TRANSFORMS_PER_REQUEST:
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   116
      raise BadRequestError("%d transforms have already been requested on this "
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   117
                            "image." % MAX_TRANSFORMS_PER_REQUEST)
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   118
828
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   119
  def _update_dimensions(self):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   120
    """Updates the width and height fields of the image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   121
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   122
    Raises:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   123
      NotImageError if the image data is not an image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   124
      BadImageError if the image data is corrupt.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   125
    """
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   126
    size = len(self._image_data)
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   127
    if size >= 6 and self._image_data.startswith("GIF"):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   128
      self._update_gif_dimensions()
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   129
    elif size >= 8 and self._image_data.startswith("\x89PNG\x0D\x0A\x1A\x0A"):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   130
      self._update_png_dimensions()
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   131
    elif size >= 2 and self._image_data.startswith("\xff\xD8"):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   132
      self._update_jpeg_dimensions()
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   133
    elif (size >= 8 and (self._image_data.startswith("II\x2a\x00") or
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   134
                         self._image_data.startswith("MM\x00\x2a"))):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   135
      self._update_tiff_dimensions()
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   136
    elif size >= 2 and self._image_data.startswith("BM"):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   137
      self._update_bmp_dimensions()
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   138
    elif size >= 4 and self._image_data.startswith("\x00\x00\x01\x00"):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   139
      self._update_ico_dimensions()
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   140
    else:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   141
      raise NotImageError("Unrecognized image format")
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   142
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   143
  def _update_gif_dimensions(self):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   144
    """Updates the width and height fields of the gif image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   145
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   146
    Raises:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   147
      BadImageError if the image string is not a valid gif image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   148
    """
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   149
    size = len(self._image_data)
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   150
    if size >= 10:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   151
      self._width, self._height = struct.unpack("<HH", self._image_data[6:10])
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   152
    else:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   153
      raise BadImageError("Corrupt GIF format")
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   154
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   155
  def _update_png_dimensions(self):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   156
    """Updates the width and height fields of the png image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   157
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   158
    Raises:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   159
      BadImageError if the image string is not a valid png image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   160
    """
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   161
    size = len(self._image_data)
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   162
    if size >= 24 and self._image_data[12:16] == "IHDR":
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   163
      self._width, self._height = struct.unpack(">II", self._image_data[16:24])
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   164
    else:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   165
      raise BadImageError("Corrupt PNG format")
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   166
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   167
  def _update_jpeg_dimensions(self):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   168
    """Updates the width and height fields of the jpeg image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   169
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   170
    Raises:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   171
      BadImageError if the image string is not a valid jpeg image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   172
    """
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   173
    size = len(self._image_data)
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   174
    offset = 2
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   175
    while offset < size:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   176
      while offset < size and ord(self._image_data[offset]) != 0xFF:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   177
        offset += 1
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   178
      while offset < size and ord(self._image_data[offset]) == 0xFF:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   179
        offset += 1
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   180
      if (offset < size and ord(self._image_data[offset]) & 0xF0 == 0xC0 and
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   181
          ord(self._image_data[offset]) != 0xC4):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   182
        offset += 4
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   183
        if offset + 4 <= size:
828
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   184
          self._height, self._width = struct.unpack(
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   185
              ">HH",
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   186
              self._image_data[offset:offset + 4])
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   187
          break
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   188
        else:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   189
          raise BadImageError("Corrupt JPEG format")
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   190
      elif offset + 3 <= size:
828
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   191
        offset += 1
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   192
        offset += struct.unpack(">H", self._image_data[offset:offset + 2])[0]
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   193
      else:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   194
        raise BadImageError("Corrupt JPEG format")
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   195
    if self._height is None or self._width is None:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   196
      raise BadImageError("Corrupt JPEG format")
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   197
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   198
  def _update_tiff_dimensions(self):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   199
    """Updates the width and height fields of the tiff image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   200
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   201
    Raises:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   202
      BadImageError if the image string is not a valid tiff image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   203
    """
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   204
    size = len(self._image_data)
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   205
    if self._image_data.startswith("II"):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   206
      endianness = "<"
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   207
    else:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   208
      endianness = ">"
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   209
    ifd_offset = struct.unpack(endianness + "I", self._image_data[4:8])[0]
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   210
    if ifd_offset + 14 <= size:
828
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   211
      ifd_size = struct.unpack(
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   212
          endianness + "H",
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   213
          self._image_data[ifd_offset:ifd_offset + 2])[0]
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   214
      ifd_offset += 2
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   215
      for unused_i in range(0, ifd_size):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   216
        if ifd_offset + 12 <= size:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   217
          tag = struct.unpack(
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   218
              endianness + "H",
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   219
              self._image_data[ifd_offset:ifd_offset + 2])[0]
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   220
          if tag == 0x100 or tag == 0x101:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   221
            value_type = struct.unpack(
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   222
                endianness + "H",
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   223
                self._image_data[ifd_offset + 2:ifd_offset + 4])[0]
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   224
            if value_type == 3:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   225
              format = endianness + "H"
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   226
              end_offset = ifd_offset + 10
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   227
            elif value_type == 4:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   228
              format = endianness + "I"
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   229
              end_offset = ifd_offset + 12
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   230
            else:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   231
              format = endianness + "B"
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   232
              end_offset = ifd_offset + 9
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   233
            if tag == 0x100:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   234
              self._width = struct.unpack(
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   235
                  format,
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   236
                  self._image_data[ifd_offset + 8:end_offset])[0]
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   237
              if self._height is not None:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   238
                break
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   239
            else:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   240
              self._height = struct.unpack(
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   241
                  format,
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   242
                  self._image_data[ifd_offset + 8:end_offset])[0]
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   243
              if self._width is not None:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   244
                break
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   245
          ifd_offset += 12
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   246
        else:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   247
          raise BadImageError("Corrupt TIFF format")
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   248
    if self._width is None or self._height is None:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   249
      raise BadImageError("Corrupt TIFF format")
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   250
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   251
  def _update_bmp_dimensions(self):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   252
    """Updates the width and height fields of the bmp image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   253
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   254
    Raises:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   255
      BadImageError if the image string is not a valid bmp image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   256
    """
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   257
    size = len(self._image_data)
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   258
    if size >= 18:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   259
      header_length = struct.unpack("<I", self._image_data[14:18])[0]
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   260
      if ((header_length == 40 or header_length == 108 or
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   261
           header_length == 124 or header_length == 64) and size >= 26):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   262
        self._width, self._height = struct.unpack("<II",
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   263
                                                  self._image_data[18:26])
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   264
      elif header_length == 12 and size >= 22:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   265
        self._width, self._height = struct.unpack("<HH",
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   266
                                                  self._image_data[18:22])
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   267
      else:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   268
        raise BadImageError("Corrupt BMP format")
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   269
    else:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   270
      raise BadImageError("Corrupt BMP format")
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   271
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   272
  def _update_ico_dimensions(self):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   273
    """Updates the width and height fields of the ico image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   274
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   275
    Raises:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   276
      BadImageError if the image string is not a valid ico image.
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   277
    """
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   278
    size = len(self._image_data)
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   279
    if size >= 8:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   280
      self._width, self._height = struct.unpack("<BB", self._image_data[6:8])
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   281
      if not self._width:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   282
        self._width = 256
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   283
      if not self._height:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   284
        self._height = 256
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   285
    else:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   286
      raise BadImageError("Corrupt ICO format")
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   287
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   288
  def resize(self, width=0, height=0):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   289
    """Resize the image maintaining the aspect ratio.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   290
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   291
    If both width and height are specified, the more restricting of the two
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   292
    values will be used when resizing the photo.  The maximum dimension allowed
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   293
    for both width and height is 4000 pixels.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   294
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   295
    Args:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   296
      width: int, width (in pixels) to change the image width to.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   297
      height: int, height (in pixels) to change the image height to.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   298
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   299
    Raises:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   300
      TypeError when width or height is not either 'int' or 'long' types.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   301
      BadRequestError when there is something wrong with the given height or
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   302
        width or if MAX_TRANSFORMS_PER_REQUEST transforms have already been
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   303
        requested on this image.
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   304
    """
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   305
    if (not isinstance(width, (int, long)) or
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   306
        not isinstance(height, (int, long))):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   307
      raise TypeError("Width and height must be integers.")
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   308
    if width < 0 or height < 0:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   309
      raise BadRequestError("Width and height must be >= 0.")
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   310
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   311
    if not width and not height:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   312
      raise BadRequestError("At least one of width or height must be > 0.")
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   313
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   314
    if width > 4000 or height > 4000:
2273
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   315
      raise BadRequestError("Both width and height must be <= 4000.")
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   316
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   317
    self._check_transform_limits()
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   318
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   319
    transform = images_service_pb.Transform()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   320
    transform.set_width(width)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   321
    transform.set_height(height)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   322
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   323
    self._transforms.append(transform)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   324
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   325
  def rotate(self, degrees):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   326
    """Rotate an image a given number of degrees clockwise.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   327
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   328
    Args:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   329
      degrees: int, must be a multiple of 90.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   330
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   331
    Raises:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   332
      TypeError when degrees is not either 'int' or 'long' types.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   333
      BadRequestError when there is something wrong with the given degrees or
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   334
      if MAX_TRANSFORMS_PER_REQUEST transforms have already been requested.
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   335
    """
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   336
    if not isinstance(degrees, (int, long)):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   337
      raise TypeError("Degrees must be integers.")
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   338
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   339
    if degrees % 90 != 0:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   340
      raise BadRequestError("degrees argument must be multiple of 90.")
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   341
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   342
    degrees = degrees % 360
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   343
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   344
    self._check_transform_limits()
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   345
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   346
    transform = images_service_pb.Transform()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   347
    transform.set_rotate(degrees)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   348
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   349
    self._transforms.append(transform)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   350
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   351
  def horizontal_flip(self):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   352
    """Flip the image horizontally.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   353
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   354
    Raises:
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   355
      BadRequestError if MAX_TRANSFORMS_PER_REQUEST transforms have already been
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   356
      requested on the image.
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   357
    """
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   358
    self._check_transform_limits()
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   359
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   360
    transform = images_service_pb.Transform()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   361
    transform.set_horizontal_flip(True)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   362
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   363
    self._transforms.append(transform)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   364
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   365
  def vertical_flip(self):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   366
    """Flip the image vertically.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   367
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   368
    Raises:
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   369
      BadRequestError if MAX_TRANSFORMS_PER_REQUEST transforms have already been
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   370
      requested on the image.
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   371
    """
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   372
    self._check_transform_limits()
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   373
    transform = images_service_pb.Transform()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   374
    transform.set_vertical_flip(True)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   375
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   376
    self._transforms.append(transform)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   377
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   378
  def _validate_crop_arg(self, val, val_name):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   379
    """Validate the given value of a Crop() method argument.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   380
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   381
    Args:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   382
      val: float, value of the argument.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   383
      val_name: str, name of the argument.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   384
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   385
    Raises:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   386
      TypeError if the args are not of type 'float'.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   387
      BadRequestError when there is something wrong with the given bounding box.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   388
    """
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   389
    if type(val) != float:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   390
      raise TypeError("arg '%s' must be of type 'float'." % val_name)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   391
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   392
    if not (0 <= val <= 1.0):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   393
      raise BadRequestError("arg '%s' must be between 0.0 and 1.0 "
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   394
                            "(inclusive)" % val_name)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   395
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   396
  def crop(self, left_x, top_y, right_x, bottom_y):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   397
    """Crop the image.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   398
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   399
    The four arguments are the scaling numbers to describe the bounding box
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   400
    which will crop the image.  The upper left point of the bounding box will
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   401
    be at (left_x*image_width, top_y*image_height) the lower right point will
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   402
    be at (right_x*image_width, bottom_y*image_height).
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   403
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   404
    Args:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   405
      left_x: float value between 0.0 and 1.0 (inclusive).
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   406
      top_y: float value between 0.0 and 1.0 (inclusive).
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   407
      right_x: float value between 0.0 and 1.0 (inclusive).
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   408
      bottom_y: float value between 0.0 and 1.0 (inclusive).
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   409
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   410
    Raises:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   411
      TypeError if the args are not of type 'float'.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   412
      BadRequestError when there is something wrong with the given bounding box
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   413
        or if MAX_TRANSFORMS_PER_REQUEST transforms have already been requested
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   414
        for this image.
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   415
    """
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   416
    self._validate_crop_arg(left_x, "left_x")
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   417
    self._validate_crop_arg(top_y, "top_y")
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   418
    self._validate_crop_arg(right_x, "right_x")
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   419
    self._validate_crop_arg(bottom_y, "bottom_y")
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   420
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   421
    if left_x >= right_x:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   422
      raise BadRequestError("left_x must be less than right_x")
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   423
    if top_y >= bottom_y:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   424
      raise BadRequestError("top_y must be less than bottom_y")
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   425
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   426
    self._check_transform_limits()
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   427
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   428
    transform = images_service_pb.Transform()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   429
    transform.set_crop_left_x(left_x)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   430
    transform.set_crop_top_y(top_y)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   431
    transform.set_crop_right_x(right_x)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   432
    transform.set_crop_bottom_y(bottom_y)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   433
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   434
    self._transforms.append(transform)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   435
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   436
  def im_feeling_lucky(self):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   437
    """Automatically adjust image contrast and color levels.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   438
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   439
    This is similar to the "I'm Feeling Lucky" button in Picasa.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   440
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   441
    Raises:
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   442
      BadRequestError if MAX_TRANSFORMS_PER_REQUEST transforms have already
2273
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   443
        been requested for this image.
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   444
    """
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   445
    self._check_transform_limits()
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   446
    transform = images_service_pb.Transform()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   447
    transform.set_autolevels(True)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   448
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   449
    self._transforms.append(transform)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   450
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   451
  def execute_transforms(self, output_encoding=PNG):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   452
    """Perform transformations on given image.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   453
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   454
    Args:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   455
      output_encoding: A value from OUTPUT_ENCODING_TYPES.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   456
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   457
    Returns:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   458
      str, image data after the transformations have been performed on it.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   459
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   460
    Raises:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   461
      BadRequestError when there is something wrong with the request
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   462
        specifications.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   463
      NotImageError when the image data given is not an image.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   464
      BadImageError when the image data given is corrupt.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   465
      LargeImageError when the image data given is too large to process.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   466
      TransformtionError when something errors during image manipulation.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   467
      Error when something unknown, but bad, happens.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   468
    """
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   469
    if output_encoding not in OUTPUT_ENCODING_TYPES:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   470
      raise BadRequestError("Output encoding type not in recognized set "
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   471
                            "%s" % OUTPUT_ENCODING_TYPES)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   472
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   473
    if not self._transforms:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   474
      raise BadRequestError("Must specify at least one transformation.")
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   475
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   476
    request = images_service_pb.ImagesTransformRequest()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   477
    response = images_service_pb.ImagesTransformResponse()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   478
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   479
    request.mutable_image().set_content(self._image_data)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   480
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   481
    for transform in self._transforms:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   482
      request.add_transform().CopyFrom(transform)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   483
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   484
    request.mutable_output().set_mime_type(output_encoding)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   485
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   486
    try:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   487
      apiproxy_stub_map.MakeSyncCall("images",
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   488
                                     "Transform",
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   489
                                     request,
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   490
                                     response)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   491
    except apiproxy_errors.ApplicationError, e:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   492
      if (e.application_error ==
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   493
          images_service_pb.ImagesServiceError.BAD_TRANSFORM_DATA):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   494
        raise BadRequestError()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   495
      elif (e.application_error ==
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   496
            images_service_pb.ImagesServiceError.NOT_IMAGE):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   497
        raise NotImageError()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   498
      elif (e.application_error ==
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   499
            images_service_pb.ImagesServiceError.BAD_IMAGE_DATA):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   500
        raise BadImageError()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   501
      elif (e.application_error ==
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   502
            images_service_pb.ImagesServiceError.IMAGE_TOO_LARGE):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   503
        raise LargeImageError()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   504
      elif (e.application_error ==
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   505
            images_service_pb.ImagesServiceError.UNSPECIFIED_ERROR):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   506
        raise TransformationError()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   507
      else:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   508
        raise Error()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   509
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   510
    self._image_data = response.image().content()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   511
    self._transforms = []
828
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   512
    self._width = None
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   513
    self._height = None
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   514
    return self._image_data
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   515
828
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   516
  @property
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   517
  def width(self):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   518
    """Gets the width of the image."""
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   519
    if self._width is None:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   520
      self._update_dimensions()
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   521
    return self._width
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   522
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   523
  @property
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   524
  def height(self):
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   525
    """Gets the height of the image."""
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   526
    if self._height is None:
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   527
      self._update_dimensions()
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   528
    return self._height
f5fd65cc3bf3 Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 109
diff changeset
   529
2273
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   530
  def histogram(self):
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   531
    """Calculates the histogram of the image.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   532
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   533
    Returns: 3 256-element lists containing the number of occurences of each
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   534
    value of each color in the order RGB. As described at
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   535
    http://en.wikipedia.org/wiki/Color_histogram for N = 256. i.e. the first
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   536
    value of the first list contains the number of pixels with a red value of
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   537
    0, the second the number with a red value of 1.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   538
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   539
    Raises:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   540
      NotImageError when the image data given is not an image.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   541
      BadImageError when the image data given is corrupt.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   542
      LargeImageError when the image data given is too large to process.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   543
      Error when something unknown, but bad, happens.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   544
    """
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   545
    request = images_service_pb.ImagesHistogramRequest()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   546
    response = images_service_pb.ImagesHistogramResponse()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   547
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   548
    request.mutable_image().set_content(self._image_data)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   549
    try:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   550
      apiproxy_stub_map.MakeSyncCall("images",
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   551
                                     "Histogram",
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   552
                                     request,
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   553
                                     response)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   554
    except apiproxy_errors.ApplicationError, e:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   555
      if (e.application_error ==
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   556
          images_service_pb.ImagesServiceError.NOT_IMAGE):
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   557
        raise NotImageError()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   558
      elif (e.application_error ==
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   559
            images_service_pb.ImagesServiceError.BAD_IMAGE_DATA):
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   560
        raise BadImageError()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   561
      elif (e.application_error ==
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   562
            images_service_pb.ImagesServiceError.IMAGE_TOO_LARGE):
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   563
        raise LargeImageError()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   564
      else:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   565
        raise Error()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   566
    histogram = response.histogram()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   567
    return [histogram.red_list(),
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   568
            histogram.green_list(),
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   569
            histogram.blue_list()]
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   570
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   571
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   572
def resize(image_data, width=0, height=0, output_encoding=PNG):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   573
  """Resize a given image file maintaining the aspect ratio.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   574
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   575
  If both width and height are specified, the more restricting of the two
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   576
  values will be used when resizing the photo.  The maximum dimension allowed
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   577
  for both width and height is 4000 pixels.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   578
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   579
  Args:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   580
    image_data: str, source image data.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   581
    width: int, width (in pixels) to change the image width to.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   582
    height: int, height (in pixels) to change the image height to.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   583
    output_encoding: a value from OUTPUT_ENCODING_TYPES.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   584
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   585
  Raises:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   586
    TypeError when width or height not either 'int' or 'long' types.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   587
    BadRequestError when there is something wrong with the given height or
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   588
      width.
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   589
    Error when something went wrong with the call.  See Image.ExecuteTransforms
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   590
      for more details.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   591
  """
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   592
  image = Image(image_data)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   593
  image.resize(width, height)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   594
  return image.execute_transforms(output_encoding=output_encoding)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   595
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   596
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   597
def rotate(image_data, degrees, output_encoding=PNG):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   598
  """Rotate a given image a given number of degrees clockwise.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   599
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   600
  Args:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   601
    image_data: str, source image data.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   602
    degrees: value from ROTATE_DEGREE_VALUES.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   603
    output_encoding: a value from OUTPUT_ENCODING_TYPES.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   604
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   605
  Raises:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   606
    TypeError when degrees is not either 'int' or 'long' types.
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   607
    BadRequestError when there is something wrong with the given degrees.
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   608
    Error when something went wrong with the call.  See Image.ExecuteTransforms
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   609
      for more details.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   610
  """
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   611
  image = Image(image_data)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   612
  image.rotate(degrees)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   613
  return image.execute_transforms(output_encoding=output_encoding)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   614
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   615
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   616
def horizontal_flip(image_data, output_encoding=PNG):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   617
  """Flip the image horizontally.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   618
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   619
  Args:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   620
    image_data: str, source image data.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   621
    output_encoding: a value from OUTPUT_ENCODING_TYPES.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   622
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   623
  Raises:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   624
    Error when something went wrong with the call.  See Image.ExecuteTransforms
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   625
      for more details.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   626
  """
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   627
  image = Image(image_data)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   628
  image.horizontal_flip()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   629
  return image.execute_transforms(output_encoding=output_encoding)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   630
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   631
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   632
def vertical_flip(image_data, output_encoding=PNG):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   633
  """Flip the image vertically.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   634
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   635
  Args:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   636
    image_data: str, source image data.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   637
    output_encoding: a value from OUTPUT_ENCODING_TYPES.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   638
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   639
  Raises:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   640
    Error when something went wrong with the call.  See Image.ExecuteTransforms
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   641
      for more details.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   642
  """
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   643
  image = Image(image_data)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   644
  image.vertical_flip()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   645
  return image.execute_transforms(output_encoding=output_encoding)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   646
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   647
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   648
def crop(image_data, left_x, top_y, right_x, bottom_y, output_encoding=PNG):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   649
  """Crop the given image.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   650
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   651
  The four arguments are the scaling numbers to describe the bounding box
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   652
  which will crop the image.  The upper left point of the bounding box will
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   653
  be at (left_x*image_width, top_y*image_height) the lower right point will
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   654
  be at (right_x*image_width, bottom_y*image_height).
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   655
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   656
  Args:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   657
    image_data: str, source image data.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   658
    left_x: float value between 0.0 and 1.0 (inclusive).
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   659
    top_y: float value between 0.0 and 1.0 (inclusive).
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   660
    right_x: float value between 0.0 and 1.0 (inclusive).
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   661
    bottom_y: float value between 0.0 and 1.0 (inclusive).
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   662
    output_encoding: a value from OUTPUT_ENCODING_TYPES.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   663
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   664
  Raises:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   665
    TypeError if the args are not of type 'float'.
1278
a7766286a7be Load /Users/solydzajs/Downloads/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 828
diff changeset
   666
    BadRequestError when there is something wrong with the given bounding box.
109
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   667
    Error when something went wrong with the call.  See Image.ExecuteTransforms
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   668
      for more details.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   669
  """
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   670
  image = Image(image_data)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   671
  image.crop(left_x, top_y, right_x, bottom_y)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   672
  return image.execute_transforms(output_encoding=output_encoding)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   673
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   674
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   675
def im_feeling_lucky(image_data, output_encoding=PNG):
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   676
  """Automatically adjust image levels.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   677
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   678
  This is similar to the "I'm Feeling Lucky" button in Picasa.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   679
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   680
  Args:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   681
    image_data: str, source image data.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   682
    output_encoding: a value from OUTPUT_ENCODING_TYPES.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   683
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   684
  Raises:
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   685
    Error when something went wrong with the call.  See Image.ExecuteTransforms
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   686
      for more details.
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   687
  """
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   688
  image = Image(image_data)
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   689
  image.im_feeling_lucky()
620f9b141567 Load ../../google_appengine into trunk/thirdparty/google_appengine.
Todd Larsen <tlarsen@google.com>
parents:
diff changeset
   690
  return image.execute_transforms(output_encoding=output_encoding)
2273
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   691
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   692
def composite(inputs, width, height, color=0, output_encoding=PNG):
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   693
  """Composite one or more images onto a canvas.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   694
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   695
  Args:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   696
    inputs: a list of tuples (image_data, x_offset, y_offset, opacity, anchor)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   697
    where
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   698
      image_data: str, source image data.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   699
      x_offset: x offset in pixels from the anchor position
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   700
      y_offset: y offset in piyels from the anchor position
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   701
      opacity: opacity of the image specified as a float in range [0.0, 1.0]
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   702
      anchor: anchoring point from ANCHOR_POINTS. The anchor point of the image
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   703
      is aligned with the same anchor point of the canvas. e.g. TOP_RIGHT would
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   704
      place the top right corner of the image at the top right corner of the
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   705
      canvas then apply the x and y offsets.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   706
    width: canvas width in pixels.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   707
    height: canvas height in pixels.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   708
    color: canvas background color encoded as a 32 bit unsigned int where each
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   709
    color channel is represented by one byte in order ARGB.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   710
    output_encoding: a value from OUTPUT_ENCODING_TYPES.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   711
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   712
  Returns:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   713
      str, image data of the composited image.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   714
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   715
  Raises:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   716
    TypeError If width, height, color, x_offset or y_offset are not of type
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   717
    int or long or if opacity is not a float
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   718
    BadRequestError If more than MAX_TRANSFORMS_PER_REQUEST compositions have
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   719
    been requested, if the canvas width or height is greater than 4000 or less
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   720
    than or equal to 0, if the color is invalid or if for any composition
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   721
    option, the opacity is outside the range [0,1] or the anchor is invalid.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   722
  """
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   723
  if (not isinstance(width, (int, long)) or
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   724
      not isinstance(height, (int, long)) or
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   725
      not isinstance(color, (int, long))):
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   726
    raise TypeError("Width, height and color must be integers.")
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   727
  if output_encoding not in OUTPUT_ENCODING_TYPES:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   728
    raise BadRequestError("Output encoding type '%s' not in recognized set "
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   729
                          "%s" % (output_encoding, OUTPUT_ENCODING_TYPES))
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   730
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   731
  if not inputs:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   732
    raise BadRequestError("Must provide at least one input")
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   733
  if len(inputs) > MAX_COMPOSITES_PER_REQUEST:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   734
    raise BadRequestError("A maximum of %d composition operations can be"
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   735
                          "performed in a single request" %
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   736
                          MAX_COMPOSITES_PER_REQUEST)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   737
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   738
  if width <= 0 or height <= 0:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   739
    raise BadRequestError("Width and height must be > 0.")
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   740
  if width > 4000 or height > 4000:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   741
    raise BadRequestError("Width and height must be <= 4000.")
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   742
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   743
  if color > 0xffffffff or color < 0:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   744
    raise BadRequestError("Invalid color")
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   745
  if color >= 0x80000000:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   746
    color -= 0x100000000
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   747
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   748
  image_map = {}
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   749
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   750
  request = images_service_pb.ImagesCompositeRequest()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   751
  response = images_service_pb.ImagesTransformResponse()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   752
  for (image, x, y, opacity, anchor) in inputs:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   753
    if not image:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   754
      raise BadRequestError("Each input must include an image")
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   755
    if (not isinstance(x, (int, long)) or
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   756
        not isinstance(y, (int, long)) or
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   757
        not isinstance(opacity, (float))):
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   758
      raise TypeError("x_offset, y_offset must be integers and opacity must"
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   759
                      "be a float")
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   760
    if x > 4000 or x < -4000:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   761
      raise BadRequestError("xOffsets must be in range [-4000, 4000]")
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   762
    if y > 4000 or y < -4000:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   763
      raise BadRequestError("yOffsets must be in range [-4000, 4000]")
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   764
    if opacity < 0 or opacity > 1:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   765
      raise BadRequestError("Opacity must be in the range 0.0 to 1.0")
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   766
    if anchor not in ANCHOR_TYPES:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   767
      raise BadRequestError("Anchor type '%s' not in recognized set %s" %
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   768
                            (anchor, ANCHOR_TYPES))
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   769
    if image not in image_map:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   770
      image_map[image] = request.image_size()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   771
      request.add_image().set_content(image)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   772
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   773
    option = request.add_options()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   774
    option.set_x_offset(x)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   775
    option.set_y_offset(y)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   776
    option.set_opacity(opacity)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   777
    option.set_anchor(anchor)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   778
    option.set_source_index(image_map[image])
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   779
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   780
  request.mutable_canvas().mutable_output().set_mime_type(output_encoding)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   781
  request.mutable_canvas().set_width(width)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   782
  request.mutable_canvas().set_height(height)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   783
  request.mutable_canvas().set_color(color)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   784
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   785
  try:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   786
    apiproxy_stub_map.MakeSyncCall("images",
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   787
                                   "Composite",
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   788
                                   request,
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   789
                                   response)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   790
  except apiproxy_errors.ApplicationError, e:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   791
    if (e.application_error ==
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   792
        images_service_pb.ImagesServiceError.BAD_TRANSFORM_DATA):
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   793
      raise BadRequestError()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   794
    elif (e.application_error ==
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   795
          images_service_pb.ImagesServiceError.NOT_IMAGE):
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   796
      raise NotImageError()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   797
    elif (e.application_error ==
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   798
          images_service_pb.ImagesServiceError.BAD_IMAGE_DATA):
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   799
      raise BadImageError()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   800
    elif (e.application_error ==
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   801
          images_service_pb.ImagesServiceError.IMAGE_TOO_LARGE):
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   802
      raise LargeImageError()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   803
    elif (e.application_error ==
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   804
          images_service_pb.ImagesServiceError.UNSPECIFIED_ERROR):
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   805
      raise TransformationError()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   806
    else:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   807
      raise Error()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   808
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   809
  return response.image().content()
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   810
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   811
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   812
def histogram(image_data):
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   813
  """Calculates the histogram of the given image.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   814
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   815
  Args:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   816
    image_data: str, source image data.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   817
  Returns: 3 256-element lists containing the number of occurences of each
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   818
  value of each color in the order RGB.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   819
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   820
  Raises:
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   821
    NotImageError when the image data given is not an image.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   822
    BadImageError when the image data given is corrupt.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   823
    LargeImageError when the image data given is too large to process.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   824
    Error when something unknown, but bad, happens.
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   825
  """
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   826
  image = Image(image_data)
e4cb9c53db3e Load /Users/solydzajs/Desktop/google_appengine into
Pawel Solyga <Pawel.Solyga@gmail.com>
parents: 1278
diff changeset
   827
  return image.histogram()