public class EncodedImage extends Image
EncodedImage
is the workhorse of Codename One. Images returned from resource files are
EncodedImage
and many API's expect it.
EncodedImage
is effectively a an image that is "hidden" and extracted as needed to remove the
memory overhead associated with loaded image. When creating an EncodedImage
only the PNG
(or JPEG etc.) is loaded to an array in RAM. Normally such images are very small (relatively) so they can be
kept in memory without much overhead.
When image information is needed (pixels) the image is decoded into RAM and kept in a weak/sort
reference (see Display.createSoftWeakRef(java.lang.Object)
). This allows the
image to be cached for performance and allows the garbage collector to reclaim it when the memory becomes
scarce.
Since the fully decoded image can be pretty big (width X height X 4
) the ability to store just the
encoded image can be pretty stark. E.g. A standard 50x100 image will take up 20,000 bytes of RAM for a
standard image but an EncodedImage
can reduce that to 1kb-2kb of RAM.
When drawing an EncodedImage
it checks the weak reference cache and if the image is cached then
it is shown otherwise the image is loaded the encoded image cache it then drawn.
EncodedImage
is not final and can be derived to produce complex image fetching strategies
e.g. the URLImage
class that can dynamically download its content from the web.
EncodedImage
can be instantiated via the create methods in the class. Pretty much any image
can be converted into an `EncodedImage` via the createFromImage(com.codename1.ui.Image, boolean)
method.
Naturally loading the image is more expensive so we want the images that are on the current form to remain in
cache (otherwise GC will thrash a lot). That's where lock()
kicks in, when lock()
is active we
keep a hard reference to the actual native image so it won't get GC'd. This significantly improves performance!
Internally this is invoked automatically for background images, icons etc. which results in a huge performance
boost. This makes sense since these images are currently showing and they will be in RAM anyway. However,
if you use a complex renderer or custom drawing UI you should lock()
your images where possible!
To verify that locking might be a problem you can launch the performance monitor tool (accessible from the simulator menu), if you get log messages that indicate that an unlocked image was drawn you might have a problem.
Modifier | Constructor and Description |
---|---|
protected |
EncodedImage(int width,
int height)
Allows subclasses to create more advanced variations of this class that
lazily store the data in an arbitrary location.
|
Modifier and Type | Method and Description |
---|---|
void |
asyncLock(Image internal)
Async lock is the equivalent of a lock operation, however it uses the given image as
the hard cache and performs the actual image loading asynchronously.
|
static EncodedImage |
create(byte[] data)
Creates an image from the given byte array
|
static EncodedImage |
create(byte[] data,
int width,
int height,
boolean opacity)
Creates an image from the given byte array with the variables set appropriately.
|
static EncodedImage |
create(InputStream i)
Creates an image from the input stream
|
static EncodedImage |
create(InputStream i,
int size)
Creates an image from the input stream, this version of the method is somewhat faster
than the version that doesn't accept size
|
static EncodedImage |
create(String i)
Creates an image from the input stream
|
static EncodedImage |
createFromImage(Image i,
boolean jpeg)
Converts an image to encoded image
|
static Image |
createFromRGB(int[] argb,
int width,
int height,
boolean jpeg)
Tries to create an encoded image from RGB which is more efficient,
however if this fails it falls back to regular RGB image.
|
static EncodedImage |
createMulti(int[] dpis,
byte[][] data)
Deprecated.
this method is meant for internal use only, it would be very expensive to use
this method for real applications. Its here for simulators and development purposes where
screen DPI/resolution can vary significantly in runtime (something that just doesn't happen on devices).
|
protected void |
drawImage(Graphics g,
Object nativeGraphics,
int x,
int y)
Callback invoked internally by Codename One to draw the image/frame onto the display.
|
protected void |
drawImage(Graphics g,
Object nativeGraphics,
int x,
int y,
int w,
int h)
Callback invoked internally by Codename One to draw the image/frame onto the display.
|
Graphics |
getGraphics()
If this is a mutable image a graphics object allowing us to draw on it
is returned.
|
int |
getHeight()
Returns the height of the image
|
Object |
getImage()
Returns the platform specific image implementation, warning the
implementation class can change between revisions of Codename One and platforms.
|
byte[] |
getImageData()
Returns the byte array data backing the image allowing the image to be stored
and discarded completely from RAM.
|
protected Image |
getInternal()
Returns the actual image represented by the encoded image, this image will
be cached in a weak/soft reference internally.
|
int |
getWidth()
Returns the width of the image
|
boolean |
isAnimation()
Returns true if this is an animated image
|
boolean |
isLocked()
Returns true if the image is locked
|
boolean |
isOpaque()
Indicates whether this image is opaque or not
|
void |
lock()
This callback indicates that a component pointing at this image is initialized, this allows
an image to make performance sensitive considerations e.g.
|
Image |
modifyAlpha(byte alpha)
Creates a new image instance with the alpha channel of opaque/translucent
pixels within the image using the new alpha value.
|
Image |
modifyAlpha(byte alpha,
int removeColor)
Creates a new image instance with the alpha channel of opaque/translucent
pixels within the image using the new alpha value.
|
protected void |
resetCache()
A subclass might choose to load asynchroniously and reset the cache when the image is ready.
|
Image |
rotate(int degrees)
Returns an instance of this image rotated by the given number of degrees.
|
void |
scale(int width,
int height)
Scale the image to the given width and height, this is a fast algorithm
that preserves translucent information
|
Image |
scaled(int width,
int height)
Returns a scaled version of this image image using the given width and height,
this is a fast algorithm that preserves translucent information.
|
EncodedImage |
scaledEncoded(int width,
int height)
Performs scaling using ImageIO to generate an encoded Image
|
Image |
scaledHeight(int height)
Scales the image to the given height while updating the width based on the
aspect ratio of the height
|
Image |
scaledSmallerRatio(int width,
int height)
Scales the image while maintaining the aspect ratio to the smaller size
image
|
Image |
scaledWidth(int width)
Scales the image to the given width while updating the height based on the
aspect ratio of the width
|
Image |
subImage(int x,
int y,
int width,
int height,
boolean processAlpha)
Extracts a subimage from the given image allowing us to breakdown a single large image
into multiple smaller images in RAM, this actually creates a standalone version
of the image for use.
|
void |
toRGB(RGBImage image,
int destX,
int destY,
int x,
int y,
int width,
int height)
Extracts data from this image into the given RGBImage
|
void |
unlock()
This callback indicates that a component pointing at this image is now deinitilized
This method may be invoked multiple times.
|
addActionListener, animate, applyMask, applyMask, applyMaskAutoScale, createImage, createImage, createImage, createImage, createImage, createImage, createImage, createIndexed, createMask, createSVG, dispose, exifRotation, exifRotation, exifRotation, fill, fireChangedEvent, flipHorizontally, flipVertically, getExifOrientationTag, getExifOrientationTag, getImageName, getRGB, getRGB, getRGBCached, getSVGDocument, isAlphaMutableImageSupported, isJPEG, isPNG, isSVG, isSVGSupported, mirror, modifyAlphaWithTranslucency, removeActionListener, requiresDrawImage, rotate180Degrees, rotate270Degrees, rotate90Degrees, scaledLargerRatio, setImageName
protected EncodedImage(int width, int height)
width
- -1 if unknown ideally the width/height should be known in advanceheight
- -1 if unknown ideally the width/height should be known in advanceprotected void resetCache()
public static EncodedImage createMulti(int[] dpis, byte[][] data)
dpis
- device DPI'sdata
- the data matching each multi-image DPIpublic static EncodedImage createFromImage(Image i, boolean jpeg)
i
- imagejpeg
- true to try and set jpeg, will do a best effort but this isn't guaranteedpublic static Image createFromRGB(int[] argb, int width, int height, boolean jpeg)
argb
- an argb arraywidth
- the width for the imageheight
- the height for the imagejpeg
- uses jpeg format internally which is opaque and could be faster/smallerpublic byte[] getImageData()
public static EncodedImage create(byte[] data)
data
- the data of the imagepublic static EncodedImage create(byte[] data, int width, int height, boolean opacity)
data
- the data of the imagewidth
- the width of the imageheight
- the height of the imageopacity
- true for an opaque imagepublic Object getImage()
public static EncodedImage create(InputStream i) throws IOException
i
- the input streamIOException
- if thrown by the input streampublic static EncodedImage create(InputStream i, int size) throws IOException
i
- the input streamsize
- the size of the streamIOException
- if thrown by the input streamprotected Image getInternal()
public boolean isLocked()
public void asyncLock(Image internal)
public void lock()
public void unlock()
public static EncodedImage create(String i) throws IOException
i
- the resourceIOException
- if thrown by the input streampublic Image subImage(int x, int y, int width, int height, boolean processAlpha)
subImage
in class Image
x
- the x offset from the imagey
- the y offset from the imagewidth
- the width of internal imagesheight
- the height of internal imagesprocessAlpha
- whether alpha should be processed as well as part of the cuttingpublic Image rotate(int degrees)
E.g. rotating an image to 45, 90 and 135 degrees is inefficient. Use rotatate to 45, 90 and then rotate the 45 to another 90 degrees to achieve the same effect with less memory.
public Image modifyAlpha(byte alpha)
modifyAlpha
in class Image
alpha
- New value for the entire alpha channelpublic Image modifyAlpha(byte alpha, int removeColor)
modifyAlpha
in class Image
alpha
- New value for the entire alpha channelremoveColor
- pixels matching this color are made transparent (alpha channel ignored)public Graphics getGraphics()
getGraphics
in class Image
public int getWidth()
public int getHeight()
protected void drawImage(Graphics g, Object nativeGraphics, int x, int y)
protected void drawImage(Graphics g, Object nativeGraphics, int x, int y, int w, int h)
public void toRGB(RGBImage image, int destX, int destY, int x, int y, int width, int height)
toRGB
in class Image
image
- RGBImage that would receive pixel datadestX
- x location within RGBImage into which the data will
be writtendestY
- y location within RGBImage into which the data will
be writtenx
- location within the source imagey
- location within the source imagewidth
- size of the image to extract from the source imageheight
- size of the image to extract from the source imagepublic Image scaledWidth(int width)
scaledWidth
in class Image
width
- the given new image widthpublic Image scaledHeight(int height)
scaledHeight
in class Image
height
- the given new image heightpublic Image scaledSmallerRatio(int width, int height)
scaledSmallerRatio
in class Image
width
- the given new image widthheight
- the given new image heightpublic EncodedImage scaledEncoded(int width, int height)
width
- the width of the image, -1 to scale based on height and preserve aspect ratioheight
- the height of the image, -1 to scale based on width and preserve aspect ratiopublic Image scaled(int width, int height)
public void scale(int width, int height)
public boolean isAnimation()
isAnimation
in class Image