ImageLayer

class ImageLayer @RememberInComposition constructor

An offscreen raster that records Java2D drawing once and draws it again as often as you like, through a transform the caller can change without re-recording.

The graphics device may hold a recording in video memory, and may discard it, such as when the display changes. A recording lost that way is dropped when it is next drawn, filtered, read back or asked for with hasContent: draw draws nothing, filter does nothing, toBufferedImage fails and hasContent answers false. Swing repaints what it lost along with it, so an owner that records on every paint needs nothing more, and one that keeps a recording across paints checks hasContent when it paints and records again.

Record a block of drawing (record(width, height, scale, block)), the pixels of a live component (record(component, scale)), or drawing aligned to the pixels of a destination it is drawn back onto (record(destination, width, height, block)), then draw the result with draw - typically from a draw block, but any Graphics2D takes it. A layer holds one recording: a second record replaces it.

The properties are plain fields, as those of androidx's GraphicsLayer are: writing one, or recording, changes nothing already painted. The next draw uses them, so whatever paints the layer repaints for a change the way it does for any other state it draws from.

A layer is Java2D, so recording drawing, drawing it back and reading it back are as free of the event dispatch thread as the images underneath. Recording a live component is not: that reads a Swing component tree, and runs on the event dispatch thread like everything else that touches one. A layer is used from one thread at a time: recording, filtering and releasing it reuse the surfaces and buffers of earlier recordings, so a draw or read-back on another thread may see the pixels of a later recording.

See also

Constructors

Link copied to clipboard
@RememberInComposition
constructor()

Properties

Link copied to clipboard

The opacity draw draws at: 0f is invisible and 1f opaque. Defaults to 1f.

Link copied to clipboard

Whether this layer holds a recording to draw, dropping one the graphics device discarded.

Link copied to clipboard

The point scaleX, scaleY and rotationZ apply around, relative to the recording's origin and in the units of its size, or null for the center of size. Defaults to null.

Link copied to clipboard

The effect draw applies to the recording, or null to draw it as recorded. Defaults to null.

Link copied to clipboard

The rotation draw draws at, in degrees about pivotOffset; a positive angle turns clockwise on screen. Defaults to 0f.

Link copied to clipboard

The horizontal scale draw draws at, about pivotOffset. Defaults to 1f.

Link copied to clipboard

The vertical scale draw draws at, about pivotOffset. Defaults to 1f.

Link copied to clipboard

The size of the recording in user-space units, whatever scale it was recorded at, or its size in device pixels for a recording aligned to a destination; 0x0 until something is recorded, and 0x0 again after release.

Link copied to clipboard

The horizontal offset draw draws at, added to its x. Defaults to 0f.

Link copied to clipboard

The vertical offset draw draws at, added to its y. Defaults to 0f.

Functions

Link copied to clipboard
fun draw(destination: Graphics2D, x: Int = 0, y: Int = 0)

Draws the recording onto destination at x, y, under this layer's transform and alpha. Draws nothing while this layer has no content.

Link copied to clipboard
fun filter(operation: BufferedImageOp)

Replaces the recording with the result of applying operation to it. Does nothing while this layer has no content.

Link copied to clipboard
fun record(component: JComponent, scale: Double = 1.0)

Records component and its descendants at the bounds the component already carries, replacing whatever this layer held.

fun record(destination: Graphics2D, width: Int, height: Int, block: (Graphics2D) -> Unit)

Records what block paints within width x height into device pixels aligned to the pixels it would paint on destination, under the destination's transform and clip, replacing whatever this layer held.

fun record(width: Int, height: Int, scale: Double = 1.0, block: (Graphics2D) -> Unit)

Records block's drawing into a transparent buffer of width x height user-space units, replacing whatever this layer held.

Link copied to clipboard
fun release()

Frees the recorded buffer and the buffers kept for reuse, leaving this layer empty: hasContent is false, size is 0x0, draw draws nothing and toBufferedImage fails.

Link copied to clipboard

Returns a copy of the recorded pixels at device resolution - the user-space size multiplied by the scale it was recorded at - untransformed and with no alpha or renderEffect applied.