Images API for legacy bundled services

App Engine provides the ability to manipulate image data using a dedicated Images service. The Images service can manipulate images, composite multiple images into a single image, convert image formats, provide image metadata such as format, width, height, and a histogram of color values.

Java 8 on App Engine supports Java's native image manipulation classes such as AWT and Java2D alongside the App Engine Images API.

The Images service can accept image data directly from the app, or it can use a Cloud Storage value. (The Images service can also use a Cloud Blobstore value, but we recommend the use of Cloud Storage.)

Images stored in Cloud Storage and Cloud Blobstore can be up to the maximum allowed value for the respective service. The transformed image is returned directly to the app, and must be less than 32 megabytes.

Cloud Storage buckets must use fine-grained Access Control Lists for the Images API to work. For buckets that have been configured for uniform bucket-level access, the Images API will not be able to fetch images in that bucket and throws the error message TransformationError. If your bucket is configured in this manner, you can disable uniform bucket-level access.

Transforming images in Java 8

The Image service API lets you apply transformations to images, using a service instead of performing image processing on the application server. The app prepares an Image object with the image data to transform, and a Transform object with instructions on how to transform the image. The app gets an ImagesService object, then calls its applyTransform() method with the Image and the Transform objects. The method returns an Image object of the transformed image.

The app gets ImagesService, Image and Transform instances using the ImagesServiceFactory.

// Get an instance of the imagesService we can use to transform images.
ImagesService imagesService = ImagesServiceFactory.getImagesService();

// Make an image directly from a byte array, and transform it.
Image image = ImagesServiceFactory.makeImage(imageBytes);
Transform resize = ImagesServiceFactory.makeResize(100, 50);
Image resizedImage = imagesService.applyTransform(resize, image);

// Write the transformed image back to a Cloud Storage object.
gcsService.createOrReplace(
    new GcsFilename(bucket, "resizedImage.jpeg"),
    new GcsFileOptions.Builder().mimeType("image/jpeg").build(),
    ByteBuffer.wrap(resizedImage.getImageData()));

Multiple transforms can be combined into a single action using a CompositeTransform instance. See the images API reference.

Available image transformations

The Images service can resize, rotate, flip, and crop images, and enhance photographs. It can also composite multiple images into a single image.

Resize

You can resize the image while maintaining the same aspect ratio. Neither the width nor the height of the resized image can exceed 4000 pixels.

Rotate

You can rotate the image in 90 degree increments.

Flip horizontally

You can flip the image horizontally.

Flip vertically

You can flip the image vertically.

Crop

You can crop the image with a given bounding box.

I'm Feeling Lucky

The "I'm Feeling Lucky" transform enhances dark and bright colors in an image and adjusts both color and optimizes contrast.

Image formats

The service accepts image data in the JPEG, PNG, WEBP, GIF (including animated GIF), BMP, TIFF and ICO formats. Transformed images can be returned in the JPEG, WEBP and PNG formats.

If the input format and the output format are different, the service converts the input data to the output format before performing the transformation.

Transforming images

The Images service can use a value from Google Cloud Storage or Blobstore as the image source for a transformation. You have two ways to transform images:

  1. Using the ImagesServiceFactory() class allows you to perform simple image transformations, such as crop, flip, and rotate.
  2. Using getServingUrl() allows you to dynamically resize and crop images, so you don't need to store different image sizes on the server. This method returns a URL that serves the image, and transformations to the image are encoded in this URL. This function assumes that the image doesn't change; if it gets modified after you get the URL, you may get unexpected results from using the URL.

Using the ImagesServiceFactory() Class

You can transform images from Cloud Storage or Blobstore if the image size is smaller than the maximum allowed by Cloud Storage or Blobstore. Note that the result of the transformation is returned directly to the app, and must not exceed the API response limit of 32 megabytes.

To transform an image from Cloud Storage or Blobstore in Java 8, you create the Image object by calling the static method ImagesServiceFactory.makeImageFromBlob(), passing it a blobstore.BlobKey value. The rest of the API behaves as expected. The applyTransform() method returns the result of the transforms, or throws an ImagesServiceFailureException if the result is larger than the maximum size of 32 megabytes.

// Make an image from a Cloud Storage object, and transform it.
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
BlobKey blobKey = blobstoreService.createGsBlobKey("/gs/" + bucket + "/image.jpeg");
Image blobImage = ImagesServiceFactory.makeImageFromBlob(blobKey);
Transform rotate = ImagesServiceFactory.makeRotate(90);
Image rotatedImage = imagesService.applyTransform(rotate, blobImage);

// Write the transformed image back to a Cloud Storage object.
gcsService.createOrReplace(
    new GcsFilename(bucket, "rotatedImage.jpeg"),
    new GcsFileOptions.Builder().mimeType("image/jpeg").build(),
    ByteBuffer.wrap(rotatedImage.getImageData()));

Using getServingUrl()

The getServingUrl() method allows you to generate a fixed, dedicated URL for an image that is stored in Cloud Storage or Blobstore. For example:

// Create a fixed dedicated URL that points to the GCS hosted file
ServingUrlOptions options = ServingUrlOptions.Builder
        .withGoogleStorageFileName("/gs/" + bucket + "/image.jpeg")
        .imageSize(150)
        .crop(true)
        .secureUrl(true);
String url = imagesService.getServingUrl(options);

The generated URL uses highly-optimized image serving infrastructure that is separate from your application. As the image is served independently from your app, it does not generate load and can be highly cost effective. The URL returned by this method is always publicly accessible but not guessable.

If you wish to stop serving the URL, delete it using the deleteServingUrl() method.

The method returns a URL encoded with the specified size and crop arguments. If you do not specify any arguments, the method returns the default URL for the image, for example:

http://lhx.ggpht.com/randomStringImageId

You can resize and crop the image dynamically by specifying the arguments in the URL. The available arguments are:

  • =sxx where xx is an integer from 0–2560 representing the length, in pixels, of the image's longest side. For example, adding =s32 resizes the image so its longest dimension is 32 pixels.
  • =sxx-c where xx is an integer from 0–2560 representing the cropped image size in pixels, and -c tells the system to crop the image.
# 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

Images and the development server

The development server uses your local machine to perform the capabilities of the Images service.

The Java development server uses the ImageIO framework to simulate the Image service. The "I'm Feeling Lucky" photo enhancement feature is not supported. The WEBP image format is only supported if a suitable decoder plugin has been installed. The Java VP8 decoder plugin can be used, for example. Note that the getServingUrl method isn't available in the development server.

A note about deletion

To stop serving an image stored in Cloud Storage or Blobstore call the deleteServingUrl() method.

You should avoid directly deleting images in Cloud Storage or Blobstore as doing so can leave them accessible through the serving URL.

Serving URLs will stop working if the application that created them is disabled or deleted, even if the underlying image remains available.

Quotas, limits, and pricing

There is currently no additional charge incurred by using the Images API. See the App Engine pricing page.

Each Images API request counts toward the Image Manipulation API Calls quota. An app can perform multiple transformations of an image in a single API call.

Data sent to the Images service counts toward the Data Sent to (Images) API quota. Data received from the Images service counts toward the Data Received from (Images) API quota.

Each transformation of an image counts toward the Transformations Executed quota.

For more information, see Quotas. You can see the current quota usage of your app by visiting the Google Cloud console Quota Details tab.

In addition to quotas, the following limits apply to the use of the Images service:

Limit Amount
maximum data size of image sent to service 32 megabytes
maximum data size of image received from service 32 megabytes
maximum size of image sent or received from service 50 megapixels