to top
Android APIs
public class

ImageReader

extends Object
implements AutoCloseable
java.lang.Object
   ↳ android.media.ImageReader

Class Overview

The ImageReader class allows direct application access to image data rendered into a Surface

Several Android media API classes accept Surface objects as targets to render to, including MediaPlayer, MediaCodec, and RenderScript Allocations. The image sizes and formats that can be used with each source vary, and should be checked in the documentation for the specific API.

The image data is encapsulated in Image objects, and multiple such objects can be accessed at the same time, up to the number specified by the maxImages constructor parameter. New images sent to an ImageReader through its Surface are queued until accessed through the acquireLatestImage() or acquireNextImage() call. Due to memory limits, an image source will eventually stall or drop Images in trying to render to the Surface if the ImageReader does not obtain and release Images at a rate equal to the production rate.

Summary

Nested Classes
interface ImageReader.OnImageAvailableListener Callback interface for being notified that a new image is available. 
Public Methods
Image acquireLatestImage()

Acquire the latest Image from the ImageReader's queue, dropping older images.

Image acquireNextImage()

Acquire the next Image from the ImageReader's queue.

void close()
Free up all the resources associated with this ImageReader.
int getHeight()
The height of each Image, in pixels.
int getImageFormat()
The image format of each Image.
int getMaxImages()
Maximum number of images that can be acquired from the ImageReader by any time (for example, with acquireNextImage()).
Surface getSurface()

Get a Surface that can be used to produce Images for this ImageReader.

int getWidth()
The width of each Image, in pixels.
static ImageReader newInstance(int width, int height, int format, int maxImages)

Create a new reader for images of the desired size and format.

void setOnImageAvailableListener(ImageReader.OnImageAvailableListener listener, Handler handler)
Register a listener to be invoked when a new image becomes available from the ImageReader.
Protected Methods
void finalize()
Invoked when the garbage collector has detected that this instance is no longer reachable.
[Expand]
Inherited Methods
From class java.lang.Object
From interface java.lang.AutoCloseable

Public Methods

public Image acquireLatestImage ()

Added in API level 19

Acquire the latest Image from the ImageReader's queue, dropping older images. Returns null if no new image is available.

This operation will acquire all the images possible from the ImageReader, but close() all images that aren't the latest. This function is recommended to use over acquireNextImage() for most use-cases, as it's more suited for real-time processing.

Note that maxImages should be at least 2 for acquireLatestImage() to be any different than acquireNextImage() - discarding all-but-the-newest Image requires temporarily acquiring two Images at once. Or more generally, calling acquireLatestImage() with less than two images of margin, that is (maxImages - currentAcquiredImages < 2) will not discard as expected.

This operation will fail by throwing an IllegalStateException if maxImages have been acquired with acquireLatestImage() or acquireNextImage(). In particular a sequence of acquireLatestImage() calls greater than getMaxImages() without calling close() in-between will exhaust the underlying queue. At such a time, IllegalStateException will be thrown until more images are released with close().

Returns
  • latest frame of image data, or null if no image data is available.
Throws
IllegalStateException if too many images are currently acquired

public Image acquireNextImage ()

Added in API level 19

Acquire the next Image from the ImageReader's queue. Returns null if no new image is available.

Warning: Consider using acquireLatestImage() instead, as it will automatically release older images, and allow slower-running processing routines to catch up to the newest frame. Usage of acquireNextImage() is recommended for batch/background processing. Incorrectly using this function can cause images to appear with an ever-increasing delay, followed by a complete stall where no new images seem to appear.

This operation will fail by throwing an IllegalStateException if maxImages have been acquired with acquireNextImage() or acquireLatestImage(). In particular a sequence of acquireNextImage() or acquireLatestImage() calls greater than maxImages without calling close() in-between will exhaust the underlying queue. At such a time, IllegalStateException will be thrown until more images are released with close().

Returns
  • a new frame of image data, or null if no image data is available.
Throws
IllegalStateException if maxImages images are currently acquired

public void close ()

Added in API level 19

Free up all the resources associated with this ImageReader.

After calling this method, this ImageReader can not be used. Calling any methods on this ImageReader and Images previously provided by acquireNextImage() or acquireLatestImage() will result in an IllegalStateException, and attempting to read from ByteBuffers returned by an earlier Plane#getBuffer call will have undefined behavior.

public int getHeight ()

Added in API level 19

The height of each Image, in pixels.

ImageReader guarantees that all Images acquired from ImageReader (for example, with acquireNextImage()) will have the same dimensions as specified in newInstance(int, int, int, int).

Returns
  • the height of an Image

public int getImageFormat ()

Added in API level 19

The image format of each Image.

ImageReader guarantees that all Images acquired from ImageReader (for example, with acquireNextImage()) will have the same format as specified in newInstance(int, int, int, int).

Returns
  • the format of an Image
See Also

public int getMaxImages ()

Added in API level 19

Maximum number of images that can be acquired from the ImageReader by any time (for example, with acquireNextImage()).

An image is considered acquired after it's returned by a function from ImageReader, and until the Image is closed to release the image back to the ImageReader.

Attempting to acquire more than maxImages concurrently will result in the acquire function throwing a IllegalStateException. Furthermore, while the max number of images have been acquired by the ImageReader user, the producer enqueueing additional images may stall until at least one image has been released.

Returns
  • Maximum number of images for this ImageReader.
See Also

public Surface getSurface ()

Added in API level 19

Get a Surface that can be used to produce Images for this ImageReader.

Until valid image data is rendered into this Surface, the acquireNextImage() method will return null. Only one source can be producing data into this Surface at the same time, although the same Surface can be reused with a different API once the first source is disconnected from the Surface.

Returns
  • A Surface to use for a drawing target for various APIs.

public int getWidth ()

Added in API level 19

The width of each Image, in pixels.

ImageReader guarantees that all Images acquired from ImageReader (for example, with acquireNextImage()) will have the same dimensions as specified in newInstance(int, int, int, int).

Returns
  • the width of an Image

public static ImageReader newInstance (int width, int height, int format, int maxImages)

Added in API level 19

Create a new reader for images of the desired size and format.

The maxImages parameter determines the maximum number of Image objects that can be be acquired from the ImageReader simultaneously. Requesting more buffers will use up more memory, so it is important to use only the minimum number necessary for the use case.

The valid sizes and formats depend on the source of the image data.

Parameters
width The width in pixels of the Images that this reader will produce.
height The height in pixels of the Images that this reader will produce.
format The format of the Image that this reader will produce. This must be one of the ImageFormat or PixelFormat constants. Note that not all formats is supported, like ImageFormat.NV21.
maxImages The maximum number of images the user will want to access simultaneously. This should be as small as possible to limit memory use. Once maxImages Images are obtained by the user, one of them has to be released before a new Image will become available for access through acquireLatestImage() or acquireNextImage(). Must be greater than 0.
See Also

public void setOnImageAvailableListener (ImageReader.OnImageAvailableListener listener, Handler handler)

Added in API level 19

Register a listener to be invoked when a new image becomes available from the ImageReader.

Parameters
listener The listener that will be run.
handler The handler on which the listener should be invoked, or null if the listener should be invoked on the calling thread's looper.
Throws
IllegalArgumentException If no handler specified and the calling thread has no looper.

Protected Methods

protected void finalize ()

Added in API level 19

Invoked when the garbage collector has detected that this instance is no longer reachable. The default implementation does nothing, but this method can be overridden to free resources.

Note that objects that override finalize are significantly more expensive than objects that don't. Finalizers may be run a long time after the object is no longer reachable, depending on memory pressure, so it's a bad idea to rely on them for cleanup. Note also that finalizers are run on a single VM-wide finalizer thread, so doing blocking work in a finalizer is a bad idea. A finalizer is usually only necessary for a class that has a native peer and needs to call a native method to destroy that peer. Even then, it's better to provide an explicit close method (and implement Closeable), and insist that callers manually dispose of instances. This works well for something like files, but less well for something like a BigInteger where typical calling code would have to deal with lots of temporaries. Unfortunately, code that creates lots of temporaries is the worst kind of code from the point of view of the single finalizer thread.

If you must use finalizers, consider at least providing your own ReferenceQueue and having your own thread process that queue.

Unlike constructors, finalizers are not automatically chained. You are responsible for calling super.finalize() yourself.

Uncaught exceptions thrown by finalizers are ignored and do not terminate the finalizer thread. See Effective Java Item 7, "Avoid finalizers" for more.

Throws
Throwable