Package limn.graphics
Class Image
java.lang.Object
limn.graphics.Image
An immutable, backend-independent bitmap: RGBA8 pixels, straight (non
premultiplied) alpha, row-major, row 0 at the top. Decoded once
(see
Images) and drawn via Canvas.drawImage(limn.graphics.Image, float, float, float, float); the GPU texture
is created lazily by each window's renderer, so one Image works
across multiple windows (whose GL contexts are not shared).
Object identity is the texture-cache key; reuse the same instance rather
than decoding the same asset repeatedly. A window's cache holds on to the
instance, and so to its pixels, for as long as it keeps the texture, which
Images.setTextureBudget(long) bounds.
An image may be animated: isAnimated(), with frames that are each an image
and a time each is shown for. Its own pixels are then those of its first frame, so whatever
draws an image and knows nothing of animation draws a still picture. Nothing moves unless
something plays it: an ImageView does, and limn.animation.ImageAnimation is
what a widget of an application's own does it with.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionlongframe(int index) One frame, as a still image of this image's size: what is shown at that moment, whole, whatever the file built it from.int@Nullable ImageframeIfReady(int index) One frame, if it is in memory now.intframeMillis(int index) intheight()booleanintbyte[]pixels()intwidth()
-
Constructor Details
-
Image
public Image(int width, int height, byte[] rgba) - Parameters:
width- pixelsheight- pixelsrgba-width*height*4bytes, straight alpha, top-down
-
-
Method Details
-
isAnimated
public boolean isAnimated()- Returns:
- whether this image has more than one frame, which something may play
-
frameCount
public int frameCount()- Returns:
- how many frames; 1 for a still image
-
frame
One frame, as a still image of this image's size: what is shown at that moment, whole, whatever the file built it from. The frame of a still image is the image. For a long animation that is decoded as it plays, a frame that is not in memory is decoded here, on the calling thread, and the frames before it with it: a player asksframeIfReady(int)instead.- Parameters:
index- from 0 toframeCount()- 1- Returns:
- the frame; the same object each time for as long as it is kept in memory
- Throws:
IndexOutOfBoundsException- if there is no such frame
-
frameIfReady
One frame, if it is in memory now. A long animation is decoded as it plays, a few frames ahead of the one shown, and this is what a player asks instead offrame(int): it answers at once, and says that the frame and the ones after it are wanted. A frame that is not ready is not waited for; the player shows the one before until it is.- Parameters:
index- from 0 toframeCount()- 1- Returns:
- the frame, or null while it is being decoded; never null for a still image, for an animation decoded whole, or for the first frame
- Throws:
IndexOutOfBoundsException- if there is no such frame
-
frameMillis
public int frameMillis(int index) - Parameters:
index- from 0 toframeCount()- 1- Returns:
- how long that frame is shown at the animation's own speed, in milliseconds; 0 for a still image
- Throws:
IndexOutOfBoundsException- if there is no such frame
-
durationMillis
public long durationMillis()- Returns:
- how long one turn of the animation takes, in milliseconds; 0 for a still image
-
loopCount
public int loopCount()- Returns:
- how many turns the animation asks for: 0 for one that does not end, which is also what a still image answers
-
width
public int width()- Returns:
- width in pixels
-
height
public int height()- Returns:
- height in pixels
-
pixels
public byte[] pixels()- Returns:
- the raw RGBA bytes (do not mutate)
-