API de Imágenes para servicios agrupados en paquetes heredados

App Engine ofrece la capacidad de manipular datos de imágenes mediante un servicio de imágenes dedicado. El servicio de Imágenes puede manipular imágenes, unir varias imágenes en una sola, convertir formatos de imagen, proporcionar metadatos de imagen como formato, ancho, altura y un histograma de valores de color.

El servicio de Imágenes puede aceptar datos de imagen directamente desde la app o puede usar un valor de Google Storage. (El servicio de imágenes también puede usar un valor de Blobstore de Cloud, pero te recomendamos usar Cloud Storage).

Las imágenes almacenadas en Cloud Storage y en Cloud Blobstore pueden alcanzar el valor máximo permitido para el servicio correspondiente. La imagen transformada se muestra directamente en la app y debe ser inferior a 32 megabytes.

Los depósitos de Cloud Storage deben usar listas de control de acceso detalladas para que funcione la API de Imágenes. En el caso de los buckets que se configuraron para el acceso uniforme a nivel de bucket, la API de Imágenes no podrá recuperar las imágenes de ese bucket y mostrará el mensaje de error TransformationError. Si tu bucket está configurado de esta manera, puedes inhabilitar el acceso uniforme a nivel de bucket.

Transforma imágenes en Python 2

En el siguiente ejemplo, se cargan datos de imagen desde Cloud Datastore, luego se usa el servicio de imágenes para cambiarle el tamaño y mostrarlo en el navegador como una imagen JPEG.

from google.appengine.api import images
from google.appengine.ext import ndb

import webapp2


class Photo(ndb.Model):
    title = ndb.StringProperty()
    full_size_image = ndb.BlobProperty()


class Thumbnailer(webapp2.RequestHandler):
    def get(self):
        if self.request.get("id"):
            photo = Photo.get_by_id(int(self.request.get("id")))

            if photo:
                img = images.Image(photo.full_size_image)
                img.resize(width=80, height=100)
                img.im_feeling_lucky()
                thumbnail = img.execute_transforms(output_encoding=images.JPEG)

                self.response.headers['Content-Type'] = 'image/jpeg'
                self.response.out.write(thumbnail)
                return

        # Either "id" wasn't provided, or there was no image with that ID
        # in the datastore.
        self.error(404)

Además de la API de imágenes, también puedes usar las transformaciones proporcionadas en la biblioteca de imágenes de Python (PIL) en tu app de Python 2.7. Solo debes declarar la biblioteca en la sección bibliotecas del archivo app.yaml. Sin embargo, si deseas usar la PIL en tu entorno local (mediante el servidor de desarrollo), también debes descargar e instalar la PIL o pillow de forma local.

Transformaciones de imágenes disponibles

El servicio de imágenes puede cambiar el tamaño, rotar, girar y recortar imágenes, y mejorar fotografías. También puede componer varias imágenes en una sola imagen.

Cambiar de tamaño

Puedes cambiar el tamaño de la imagen manteniendo la misma proporción. Ni el ancho ni el alto de la imagen redimensionada pueden exceder los 4,000 píxeles.

Rotar

Puedes rotar la imagen en incrementos de 90 grados.

Girar de forma horizontal

Puedes girar la imagen horizontalmente.

Girar de forma vertical

Puedes girar la imagen verticalmente.

Recortar

Puedes recortar la imagen con un cuadro de límite dado.

Voy a tener suerte

La transformación "Voy a tener suerte" mejora los colores oscuros y brillantes de una imagen, ajusta ambos colores y optimiza el contraste.

Formatos de imagen

El servicio acepta datos de imagen en los formatos JPEG, PNG, WEBP, GIF (incluido GIF animado), BMP, TIFF y también ICO. Las imágenes transformadas se pueden mostrar en los formatos JPEG, WEBP y PNG.

Si el formato de entrada y el formato de salida son diferentes, el servicio convierte los datos de entrada al formato de salida antes de hacer la transformación.

Cómo transformar imágenes

El servicio de Imágenes puede usar un valor de Google Cloud Storage o Blobstore como fuente de imágenes para una transformación. Existen dos formas de transformar imágenes:

  1. Usar la clase Image() te permite realizar transformaciones de imágenes simples como recortar, girar y rotar.
  2. Usar get_serving_url() te permite cambiar el tamaño de las imágenes y recortarlas de manera dinámica para no tener que almacenar distintos tamaños de imagen en el servidor. Con este método, se muestra una URL que entrega la imagen, y las transformaciones realizadas a la imagen se codifican en esta URL. En esta función, se supone que la imagen no cambia. Si se modifica después de obtener la URL, es posible que obtengas resultados inesperados cuando la usas.

Usa la clase Image()

Puedes transformar imágenes de Cloud Storage o Blobstore si el tamaño de la imagen es menor al máximo permitido por estos dos. Ten en cuenta que el resultado de la transformación se muestra directamente en la app y no debe exceder el límite de respuesta de la API de 32 megabytes.

Para transformar una imagen desde Cloud Storage o Blobstore en Python 2, en lugar de configurar el argumento image_data del constructor de Image con los datos de la imagen, configura el argumento blob_key con la clave Blobstore cuyo valor sea la imagen. El resto de la API se comporta de la forma esperada. El método execute_transforms() muestra el resultado de las transformaciones o genera un LargeImageError si el resultado es mayor que el tamaño máximo de 32 megabytes.

from google.appengine.api import images
from google.appengine.ext import blobstore

import webapp2


class Thumbnailer(webapp2.RequestHandler):
    def get(self):
        blob_key = self.request.get("blob_key")
        if blob_key:
            blob_info = blobstore.get(blob_key)

            if blob_info:
                img = images.Image(blob_key=blob_key)
                img.resize(width=80, height=100)
                img.im_feeling_lucky()
                thumbnail = img.execute_transforms(output_encoding=images.JPEG)

                self.response.headers['Content-Type'] = 'image/jpeg'
                self.response.out.write(thumbnail)
                return

        # Either "blob_key" wasn't provided, or there was no value with that ID
        # in the Blobstore.
        self.error(404)

Usa get_serving_url()

Además de la API de imágenes, también puedes usar las transformaciones proporcionadas en la biblioteca de imágenes de Python (PIL) en tu app de Python 2.7. Para ello, declara la biblioteca en la sección bibliotecas del archivo app.yaml.

Para usar la PIL en el servidor de desarrollo, descarga e instala la PIL o pillow de forma local.

El método get_serving_url() permite generar una URL fija y dedicada de una imagen almacenada en Cloud Storage o Blobstore. Por ejemplo:

url = images.get_serving_url(
    blob_key, size=150, crop=True, secure_url=True)

La URL generada utiliza una infraestructura de entrega de imágenes altamente optimizada que está separada de tu aplicación. Como la imagen se entrega independientemente de tu aplicación, no genera carga y puede ser altamente rentable. La URL que muestra este método siempre es de acceso público, pero no predecible.

Si ya no quieres entregar la URL, bórrala con la función delete_serving_url().

El método muestra una URL codificada con el tamaño especificado y los argumentos de recorte. Si no especificas ningún argumento, el método muestra la URL predeterminada de la imagen, por ejemplo:

http://lhx.ggpht.com/randomStringImageId

Puedes cambiar el tamaño de la imagen y recortarla de forma dinámica especificando los argumentos en la URL. Los argumentos disponibles son los siguientes:

  • =sxx en el que xx es un número entero de 0 a 2,560 que representa la longitud, en píxeles, del lado más largo de la imagen. Por ejemplo, si agregas =s32, se cambia el tamaño de la imagen para que su dimensión más larga sea de 32 píxeles.
  • =sxx-c en el que xx es un número entero de 0 a 2,560 que representa el tamaño de la imagen recortada en píxeles, y -c le dice al sistema que recorte la imagen.
# Resize the image to 32 pixels (aspect-ratio preserved)
http://lhx.ggpht.com/randomStringImageId=s32

# Crop the image to 32 pixels
http://lhx.ggpht.com/randomStringImageId=s32-c

Imágenes y servidor de desarrollo

El servidor de desarrollo usa tu máquina local para ejecutar las capacidades del servicio de imágenes.

El servidor de desarrollo de Python usa la Biblioteca de imágenes de Python (PIL) para simular el servicio de imágenes. Esta biblioteca no está incluida en la biblioteca estándar de Python o en el SDK y se debe instalar por separado. La bifurcación pillow también funciona. El formato de imagen WEBP solo se admite si se instaló un complemento de decodificador PIL adecuado.

Una aclaración sobre la eliminación

Para dejar de entregar una imagen almacenada en Cloud Storage o en Blobstore, llama a la función delete_serving_url().

Debes evitar borrar imágenes de manera directa en Cloud Storage o Blobstore, ya que hacerlo puede inhabilitar el acceso a estas a través de la URL activa.

Las URL activas dejarán de funcionar si la aplicación que las creó se inhabilita o se borra, incluso si la imagen subyacente permanece disponible.

Cuotas, límites y precios

En este momento el uso de la API de Imágenes no genera ningún cargo adicional. Consulta la página de precios de App Engine.

Cada solicitud a la API de imágenes se tiene en cuenta para la cuota de llamadas a la API de manipulación de imágenes. Una aplicación puede realizar varias transformaciones de una imagen en una sola llamada a la API.

Los datos enviados al servicio de imágenes se consideran dentro de la cuota de datos enviados a la API (de Imágenes). Los datos recibidos del servicio de imágenes se tienen en cuenta para la cuota de datos recibidos de la API (de imágenes).

Cada transformación de una imagen se considera dentro de la cuota de transformaciones ejecutadas.

Para obtener más información, consulta Cuotas. Para ver el uso actual de la cuota de tu app, visita la pestaña de detalles de cuotas de la consola de Google Cloud.

Además de las cuotas, se aplican los siguientes límites al uso del servicio de imágenes:

Límite Importe
tamaño máximo de datos de la imagen enviada al servicio 32 megabytes
tamaño máximo de datos de la imagen recibida del servicio 32 megabytes
tamaño máximo de datos de la imagen enviada al servicio o recibida de este 50 megapíxeles