def composite_async()

in src/google/appengine/api/images/__init__.py [0:0]


def composite_async(inputs,
                    width,
                    height,
                    color=0,
                    output_encoding=PNG,
                    quality=None,
                    rpc=None):
  """Asynchronously composites one or more images onto a canvas.

  Args:
    inputs: A list of tuples (`image_data`, `x_offset`, `y_offset`, `opacity`,
        `anchor`), where: - image_data String of the source image data. -
          x_offset X offset, in pixels from the anchor position. - y_offset Y
          offset, in piyels from the anchor position. - opacity Opacity of the
          image, specified as a float in range [0.0, 1.0] - anchor Anchoring
          point from `ANCHOR_POINTS`. The anchor point of the image is aligned
          with the same anchor point of the canvas. For example, `TOP_RIGHT`
          would place the top right corner of the image at the top right corner
          of the canvas, then apply the x and y offsets.
    width: Canvas width, in pixels.
    height: Canvas height, in pixels.
    color: Canvas background color, encoded as a 32-bit unsigned integer, where
      each color channel is represented by one byte in ARGB order.
    output_encoding: A value from `OUTPUT_ENCODING_TYPES`.
    quality: A value between 1 and 100 to specify the quality of the encoding.
      This value is only used for JPEG quality control.
    rpc: Optional UserRPC object.

  Returns:
    A UserRPC object.

  Raises:
    TypeError: If `width`, `height`, `color`, `x_offset`, or `y_offset` are not
        an integer or long, or if `opacity` is not a float.
    BadRequestError: If more than `MAX_TRANSFORMS_PER_REQUEST` compositions
        have been requested, if the canvas width or height is greater than
        4000 or less than or equal to 0, if the color is invalid, if the opacity
        is outside the range [0,1] for any composition option, or the anchor is
        invalid.
  """
  if (not isinstance(width, six.integer_types) or
      not isinstance(height, six.integer_types) or
      not isinstance(color, six.integer_types)):
    raise TypeError("Width, height and color must be integers.")
  if output_encoding not in OUTPUT_ENCODING_TYPES:
    raise BadRequestError("Output encoding type '%s' not in recognized set "
                          "%s" % (output_encoding, OUTPUT_ENCODING_TYPES))

  if quality is not None:
    if not isinstance(quality, six.integer_types):
      raise TypeError("Quality must be an integer.")
    if quality > 100 or quality < 1:
      raise BadRequestError("Quality must be between 1 and 100.")

  if not inputs:
    raise BadRequestError("Must provide at least one input")
  if len(inputs) > MAX_COMPOSITES_PER_REQUEST:
    raise BadRequestError("A maximum of %d composition operations can be"
                          "performed in a single request" %
                          MAX_COMPOSITES_PER_REQUEST)

  if width <= 0 or height <= 0:
    raise BadRequestError("Width and height must be > 0.")
  if width > 4000 or height > 4000:
    raise BadRequestError("Width and height must be <= 4000.")

  if color > 0xffffffff or color < 0:
    raise BadRequestError("Invalid color")

  if color >= 0x80000000:
    color -= 0x100000000

  image_map = {}

  request = images_service_pb2.ImagesCompositeRequest()
  response = images_service_pb2.ImagesTransformResponse()
  for (image, x, y, opacity, anchor) in inputs:
    if not image:
      raise BadRequestError("Each input must include an image")
    if (not isinstance(x, six.integer_types) or
        not isinstance(y, six.integer_types) or
        not isinstance(opacity, (float))):
      raise TypeError("x_offset, y_offset must be integers and opacity must"
                      "be a float")
    if x > 4000 or x < -4000:
      raise BadRequestError("xOffsets must be in range [-4000, 4000]")
    if y > 4000 or y < -4000:
      raise BadRequestError("yOffsets must be in range [-4000, 4000]")
    if opacity < 0 or opacity > 1:
      raise BadRequestError("Opacity must be in the range 0.0 to 1.0")
    if anchor not in ANCHOR_TYPES:
      raise BadRequestError("Anchor type '%s' not in recognized set %s" %
                            (anchor, ANCHOR_TYPES))
    if image not in image_map:
      image_map[image] = len(request.image)

      if isinstance(image, Image):
        image._set_imagedata(request.image.add())
      else:
        request.image.add().content = image

    option = request.options.add()
    option.x_offset = x
    option.y_offset = y
    option.opacity = opacity
    option.anchor = anchor
    option.source_index = image_map[image]

  request.canvas.output.mime_type = output_encoding
  request.canvas.width = width
  request.canvas.height = height
  request.canvas.color = color

  if ((output_encoding == JPEG or output_encoding == WEBP) and
      (quality is not None)):
    request.canvas.output.quality = quality

  def composite_hook(rpc):
    """Checks success, handles exceptions, and returns the converted RPC result.

    Args:
      rpc: A UserRPC object.

    Returns:
      Images bytes of the composite image.

    Raises:
      See `composite_async` for more details.
    """
    try:
      rpc.check_success()
    except apiproxy_errors.ApplicationError as e:
      raise _ToImagesError(e)
    return rpc.response.image.content

  return _make_async_call(rpc, "Composite", request, response, composite_hook,
                          None)