ImageWriter
open class ImageWriter : AutoCloseable
kotlin.Any | |
↳ | android.media.ImageWriter |
The ImageWriter class allows an application to produce Image data into a android.view.Surface
, and have it be consumed by another component like CameraDevice
.
Several Android API classes can provide input Surface
objects for ImageWriter to produce data into, including MediaCodec
(encoder), CameraCaptureSession
(reprocessing input), ImageReader
, etc.
The input Image data is encapsulated in Image
objects. To produce Image data into a destination Surface
, the application can get an input Image via dequeueInputImage
then write Image data into it. Multiple such Image
objects can be dequeued at the same time and queued back in any order, up to the number specified by the maxImages
constructor parameter.
If the application already has an Image from ImageReader
, the application can directly queue this Image into the ImageWriter (via queueInputImage
), potentially with zero buffer copies. This even works if the image format of the ImageWriter is PRIVATE
, and prior to Android P is the only way to enqueue images into such an ImageWriter. Starting in Android P private images may also be accessed through their hardware buffers (when available) through the Image.getHardwareBuffer()
method. Attempting to access the planes of a private image, will return an empty array.
Once new input Images are queued into an ImageWriter, it's up to the downstream components (e.g. ImageReader
or android.hardware.camera2.CameraDevice
) to consume the Images. If the downstream components cannot consume the Images at least as fast as the ImageWriter production rate, the dequeueInputImage
call will eventually block and the application will have to drop input frames.
If the consumer component that provided the input Surface
abandons the Surface
, queueing
or dequeueing
an Image
will throw an IllegalStateException
.
Summary
Nested classes | |
---|---|
Builder class for |
|
abstract |
ImageWriter callback interface, used to to asynchronously notify the application of various ImageWriter events. |
Public methods | |
---|---|
open Unit |
close() Free up all the resources associated with this ImageWriter. |
open Image! |
Dequeue the next available input Image for the application to produce data into. |
open Int |
Get the ImageWriter dataspace. |
open Int |
Get the ImageWriter format. |
open Int |
Get the ImageWriter hardwareBuffer format. |
open Int |
The height of |
open Int |
Maximum number of Images that can be dequeued from the ImageWriter simultaneously (for example, with |
open Long |
getUsage() Get the ImageWriter usage flag. |
open Int |
getWidth() The width of |
open static ImageWriter |
newInstance(surface: Surface, maxImages: Int) Create a new ImageWriter. |
open static ImageWriter |
newInstance(surface: Surface, maxImages: Int, format: Int) Create a new ImageWriter with given number of max Images and format. |
open Unit |
queueInputImage(image: Image!) Queue an input |
open Unit |
setOnImageReleasedListener(listener: ImageWriter.OnImageReleasedListener!, handler: Handler!) Register a listener to be invoked when an input Image is returned to the ImageWriter. |
Protected methods | |
---|---|
open Unit |
finalize() |
Public methods
close
open fun close(): Unit
Free up all the resources associated with this ImageWriter.
After calling this method, this ImageWriter cannot be used. Calling any methods on this ImageWriter and Images previously provided by dequeueInputImage()
will result in an IllegalStateException
, and attempting to write into ByteBuffers
returned by an earlier Plane#getBuffer
call will have undefined behavior.
Exceptions | |
---|---|
java.lang.Exception |
if this resource cannot be closed |
dequeueInputImage
open fun dequeueInputImage(): Image!
Dequeue the next available input Image for the application to produce data into.
This method requests a new input Image from ImageWriter. The application owns this Image after this call. Once the application fills the Image data, it is expected to return this Image back to ImageWriter for downstream consumer components (e.g. android.hardware.camera2.CameraDevice
) to consume. The Image can be returned to ImageWriter via queueInputImage
or Image.close()
.
This call will block if all available input images have been queued by the application and the downstream consumer has not yet consumed any. When an Image is consumed by the downstream consumer and released, an OnImageReleasedListener.onImageReleased
callback will be fired, which indicates that there is one input Image available. For non- PRIVATE
formats ( ImageWriter.getFormat()
!= ImageFormat.PRIVATE
), it is recommended to dequeue the next Image only after this callback is fired, in the steady state.
If the format of ImageWriter is PRIVATE
( ImageWriter.getFormat()
== ImageFormat.PRIVATE
), the image buffer is accessible to the application only through the hardware buffer obtained through Image.getHardwareBuffer()
. (On Android versions prior to P, dequeueing private buffers will cause an IllegalStateException
to be thrown). Alternatively, the application can acquire images from some other component (e.g. an ImageReader
), and queue them directly to this ImageWriter via the queueInputImage()
method.
Return | |
---|---|
Image! |
The next available input Image from this ImageWriter. |
Exceptions | |
---|---|
java.lang.IllegalStateException |
if maxImages Images are currently dequeued, or the input Surface has been abandoned by the consumer component that provided the Surface . Prior to Android P, throws if the ImageWriter format is PRIVATE . |
getDataSpace
open fun getDataSpace(): Int
Get the ImageWriter dataspace.
Use this function if the ImageWriter instance is created by builder pattern ImageWriter.Builder
and Builder.setDataSpace
.
getFormat
open fun getFormat(): Int
Get the ImageWriter format.
This format may be different than the Image format returned by Image.getFormat()
. However, if the ImageWriter format is PRIVATE
, calling dequeueInputImage()
will result in an IllegalStateException
.
Return | |
---|---|
Int |
The ImageWriter format. |
getHardwareBufferFormat
open fun getHardwareBufferFormat(): Int
Get the ImageWriter hardwareBuffer format.
Use this function if the ImageWriter instance is created by builder pattern ImageWriter.Builder
and using Builder.setHardwareBufferFormat
and Builder.setDataSpace
.
getHeight
open fun getHeight(): Int
The height of Images
, in pixels.
If Builder.setWidthAndHeight
is not called, the default height of the Image depends on the Surface provided by customer end-point.
Return | |
---|---|
Int |
the expected height of an Image. |
getMaxImages
open fun getMaxImages(): Int
Maximum number of Images that can be dequeued from the ImageWriter simultaneously (for example, with dequeueInputImage()
).
An Image is considered dequeued after it's returned by dequeueInputImage()
from ImageWriter, and until the Image is sent back to ImageWriter via queueInputImage
, or Image.close()
.
Attempting to dequeue more than maxImages
concurrently will result in the dequeueInputImage()
function throwing an IllegalStateException
.
Return | |
---|---|
Int |
Maximum number of Images that can be dequeued from this ImageWriter. |
getUsage
open fun getUsage(): Long
Get the ImageWriter usage flag.
It is not recommended to use this function if Builder.setUsage
is not called. Invalid usage value will be returned if so.
getWidth
open fun getWidth(): Int
The width of Images
, in pixels.
If Builder.setWidthAndHeight
is not called, the default width of the Image depends on the Surface provided by customer end-point.
Return | |
---|---|
Int |
the expected actual width of an Image. |
newInstance
open static fun newInstance(
surface: Surface,
maxImages: Int
): ImageWriter
Create a new ImageWriter.
The maxImages
parameter determines the maximum number of Image
objects that can be be dequeued from the ImageWriter
simultaneously. Requesting more buffers will use up more memory, so it is important to use only the minimum number necessary.
The input Image size and format depend on the Surface that is provided by the downstream consumer end-point.
Parameters | |
---|---|
surface |
Surface: The destination Surface this writer produces Image data into. This value cannot be null . |
maxImages |
Int: The maximum number of Images the user will want to access simultaneously for producing Image data. This should be as small as possible to limit memory use. Once maxImages Images are dequeued by the user, one of them has to be queued back before a new Image can be dequeued for access via dequeueInputImage() . Value is 1 or greater |
Return | |
---|---|
ImageWriter |
a new ImageWriter instance. This value cannot be null . |
newInstance
open static fun newInstance(
surface: Surface,
maxImages: Int,
format: Int
): ImageWriter
Create a new ImageWriter with given number of max Images and format.
The maxImages
parameter determines the maximum number of Image
objects that can be be dequeued from the ImageWriter
simultaneously. Requesting more buffers will use up more memory, so it is important to use only the minimum number necessary.
The format specifies the image format of this ImageWriter. The format from the surface
will be overridden with this format. For example, if the surface is obtained from a android.graphics.SurfaceTexture
, the default format may be PixelFormat.RGBA_8888
. If the application creates an ImageWriter with this surface and ImageFormat.PRIVATE
, this ImageWriter will be able to operate with ImageFormat.PRIVATE
Images.
Note that the consumer end-point may or may not be able to support Images with different format, for such case, the application should only use this method if the consumer is able to consume such images.
The input Image size depends on the Surface that is provided by the downstream consumer end-point.
Return | |
---|---|
ImageWriter |
a new ImageWriter instance. This value cannot be null . |
queueInputImage
open fun queueInputImage(image: Image!): Unit
Queue an input Image
back to ImageWriter for the downstream consumer to access.
The input Image
could be from ImageReader (acquired via ImageReader.acquireNextImage
or ImageReader.acquireLatestImage
), or from this ImageWriter (acquired via dequeueInputImage
). In the former case, the Image data will be moved to this ImageWriter. Note that the Image properties (size, format, strides, etc.) must be the same as the properties of the images dequeued from this ImageWriter. In the latter case, the application has filled the input image with data. This method then passes the filled buffer to the downstream consumer. In both cases, it's up to the caller to ensure that the Image timestamp (in nanoseconds) is correctly set, as the downstream component may want to use it to indicate the Image data capture time.
After this method is called and the downstream consumer consumes and releases the Image, an OnImageReleasedListener.onImageReleased
callback will fire. The application can use this callback to avoid sending Images faster than the downstream consumer processing rate in steady state.
Passing in an Image from some other component (e.g. an ImageReader
) requires a free input Image from this ImageWriter as the destination. In this case, this call will block, as dequeueInputImage
does, if there are no free Images available. To avoid blocking, the application should ensure that there is at least one free Image available in this ImageWriter before calling this method.
After this call, the input Image is no longer valid for further access, as if the Image is closed
. Attempting to access the ByteBuffers
returned by an earlier Plane#getBuffer
call will result in an IllegalStateException
.
Parameters | |
---|---|
image |
Image!: The Image to be queued back to ImageWriter for future consumption. |
Exceptions | |
---|---|
java.lang.IllegalStateException |
if the image was already queued previously, or the image was aborted previously, or the input Surface has been abandoned by the consumer component that provided the Surface . |
See Also
setOnImageReleasedListener
open fun setOnImageReleasedListener(
listener: ImageWriter.OnImageReleasedListener!,
handler: Handler!
): Unit
Register a listener to be invoked when an input Image is returned to the ImageWriter.
Parameters | |
---|---|
listener |
ImageWriter.OnImageReleasedListener!: The listener that will be run. |
handler |
Handler!: The handler on which the listener should be invoked, or null if the listener should be invoked on the calling thread's looper. |
Exceptions | |
---|---|
java.lang.IllegalArgumentException |
If no handler specified and the calling thread has no looper. |
Protected methods
finalize
protected open fun finalize(): Unit
Exceptions | |
---|---|
java.lang.Throwable |
the Exception raised by this method |