Images

Immutable Images

Overview

Immutable images are graphical resources that can be accessed with a call to ej.microui.display.Image.getImage() or ej.microui.display.ResourceImage.loadImage(). As their name suggests, immutable images can not be modified. Therefore, there is no way to get a Graphics Context to draw into these images. To be displayed, these images have to be converted from their source format to a RAW format. The conversion can either be done:

  • At build-time, using the Image Generator.

  • At run-time, using the relevant decoder library.

Immutable images are declared in Classpath *.images.list files (or in *.imagesext.list for an external resource, see External Images).

digraph D {

    internalImage [shape=diamond, label="internal?"]
    imagesList [shape=box, label="*.images.list"]
    imagesExt [shape=box, label="*.imagesext.list"]
    subgraph cluster_image {
        label ="Image"
        internalImage -> imagesList [label="yes"]
        internalImage -> imagesExt [label="no=external"]
    }
}

The file format is a standard Java properties file. Each line contains a /-separated resource path relative to the Classpath root referring to a standard image file (e.g. .png, .jpg). The resource may be followed by an optional parameter (separated by a :) which defines and/or describes the image output file format (RAW format). When no option is specified, the image is embedded as-is and will be decoded at run-time. Example:

# The following image is embedded as
# a PNG resource (decoded at run-time)
com/mycompany/MyImage1.png

# The following image is embedded as
# a 16-bit encoding without transparency (decoded at build-time)
com/mycompany/MyImage2.png:RGB565

# The following image is embedded as
# a 16-bit encoding with transparency (decoded at build-time)
com/mycompany/MyImage3.png:ARGB1555

Configuration File

Here is the format of the *.images.list files.

ConfigFile          ::= Line [ 'EOL' Line ]*
Line                ::= ImagePath [ ':' ImageOption ]*
ImagePath           ::= Identifier [ '/' Identifier ]*
ImageOption         ::= [^:]*
Identifier          ::= Letter [ LetterOrDigit ]*
Letter              ::= 'a-zA-Z_$'
LetterOrDigit       ::= 'a-zA-Z_$0-9'

Unspecified Output Format

When no output format is set in the image list file, the image is embedded without any conversion / compression. This allows you to embed the resource as-is, in order to keep the source image characteristics (compression, bpp, size, etc.). This option produces the same result as specifying an image as a resource in the MicroEJ launcher (i.e. in a .resources.list file).

Refer to the platform specification to retrieve the list of runtime decoders.

Advantages

  • Preserves the image characteristics.

  • Preserves the original image compression.

Disadvantages

  • Requires an image runtime decoder.

  • Requires some RAM in which to store the decoded image.

  • Requires execution time to decode the image.

image1

Display Output Format

It encodes the image into the exact display memory representation. If the image to encode contains some transparent pixels, the output file will embed the transparency according to the display’s implementation capacity. When all pixels are fully opaque, no extra information will be stored in the output file in order to free up some memory space.

Note

When the display memory representation is standard, the display output format is automatically replaced by a standard format.

Advantages

  • Drawing an image is very fast because no pixel conversion is required at runtime.

  • Supports alpha encoding when the display pixel format allows it.

Disadvantages

  • No compression: the image size in bytes is proportional to the number of pixels.

image1:display

Standard Output Formats

Some image formats are well known and commonly implemented by GPUs.

Refer to the platform specification to retrieve the list of natively supported formats.

Advantages

  • The pixel layout and bit format are standard, so it is easy to manipulate these images on the C-side.

  • Drawing an image is very fast when the display driver recognizes the format (with or without transparency).

Disadvantages

  • No compression: the image size in bytes is proportional to the number of pixels.

  • Slower than display format when the display driver does not recognize the format: a pixel conversion is required at runtime.

Here is the list of the standard formats:

  • Transparent images:

    • ARGB8888: 32-bit format, 8 bits for transparency, 8 per color,

    • ARGB4444: 16-bit format, 4 bits for transparency, 4 per color,

    • ARGB1555: 16-bit format, 1 bit for transparency, 5 per color.

  • Transparent images with premultiplied alpha (RGB and alpha are linked)

    • ARGB8888_PRE: 32-bit format, 8 bits for transparency, 8 per color,

    • ARGB4444_PRE: 16-bit format, 4 bits for transparency, 4 per color,

    • ARGB1555_PRE: 16-bit format, 1 bit for transparency, 5 per color.

  • Opaque images:

    • RGB888: 24-bit format, 8 per color,

    • RGB565: 16-bit format, 5 for red, 6 for green, 5 for blue.

  • Alpha images, only transparency is encoded (the color applied when drawing the image is the current GraphicsContext color):

    • A8: 8-bit format,

    • A4: 4-bit format,

    • A2: 2-bit format,

    • A1: 1-bit format.

Examples:

image1:ARGB8888
image2:RGB565
image3:A4

Grayscale Output Formats

Some grayscale formats may be useful on grayscale or black and white displays.

Advantages

  • Reduced footprint with less bits per pixels.

Disadvantages

  • No compression: the image size in bytes is proportional to the number of pixels.

  • Slower: a pixel conversion is required at runtime.

Here is the list of the grayscale formats:

  • With transparency:

    • AC44: 4 bits for transparency, 4 bits with grayscale conversion,

    • AC22: 2 bits for transparency, 2 bits with grayscale conversion,

    • AC11: 1 bit for transparency, 1 bit with grayscale conversion.

  • Without transparency:

    • C4: 4 bits with grayscale conversion,

    • C2: 2 bits with grayscale conversion,

    • C1: 1 bit with grayscale conversion.

Examples:

image1:AC44
image2:C2

Compressed Output Formats

Some image formats are compressed using run-length encoding. This compression is lossless. The principle is that identical consecutive pixels are stored as one entry (value and count). The more the consecutive pixels are identical, the more the compression is efficient.

Advantages

  • Good compression when there are a lot of identical consecutive pixels.

Disadvantages

  • Drawing an image may be slightly slower than using an uncompressed format supported by the GPU.

  • Not designed for images with many different pixel colors: in such case, the output file size may be larger than the original image file.

Here is the list of the compressed formats:

  • ARGB1565_RLE: 16-bit format, 1 bit for transparency, 5 for red, 6 for green, 5 for blue. (Formerly named RLE1 up to UI Pack 13.3.X.)

  • A8_RLE: similar to A8.

image1:ARGB1565_RLE
image2:RLE1 # Deprecated
image3:A8_RLE

Alpha Format

As described above, the formats A8, A4, A2, A1 and A8_RLE (also called Picto) only handle the opacity information. The source image can be transparent or not, colored or grayscaled. The alpha format provides two options to interpret the source image’s pixels:

  • grayscale: The source image is first grayscaled and then drawn over a white background. The black pixels are encoded as fully opaque pixels, the white pixels as fully transparent pixels and gray pixels as transparent pixels (the closer the pixel is to black, the more opaque the encoded opacity is).

  • alpha: Only the opacity component is encoded (the R-G-B components are ignored).

  • no option: same as grayscale (backward compatibility).

image1:A8:grayscale
image2:A8_RLE:alpha
image3:A4

Note

The MicroUI ResourceImage OutputFormat A8 encodes in the same way as the option alpha.

Expected Result

The following table summarizes the usage of the different formats and the actual result on a white background.

Image Output Formats Usage

Format

Source

Result

ARGB8888

../../../_images/transparent.png ../../../_images/argb8888.png

ARGB4444

../../../_images/transparent.png ../../../_images/argb4444.png

ARGB1555

../../../_images/transparent.png ../../../_images/argb1555.png

ARGB8888_PRE

../../../_images/transparent.png ../../../_images/argb8888.png

ARGB4444_PRE

../../../_images/transparent.png ../../../_images/argb4444.png

ARGB1555_PRE

../../../_images/transparent.png ../../../_images/argb1555.png

RGB888

../../../_images/opaque.png ../../../_images/rgb888_o.png
../../../_images/transparent.png ../../../_images/rgb888_t.png

RGB565

../../../_images/opaque.png ../../../_images/rgb565_o.png
../../../_images/transparent.png ../../../_images/rgb565_t.png

A8

../../../_images/picto.png ../../../_images/a8.png

With 0x0000ff as color

and option grayscale

../../../_images/a8_c.png

With 0x0000ff as color

and option alpha

../../../_images/a8_c_a.png
../../../_images/a8_a.png ../../../_images/a8_a.png

With 0x0000ff as color

and option grayscale

../../../_images/a8_w.png

With 0x0000ff as color

and option alpha

../../../_images/a8_c.png

A4

../../../_images/picto.png

option grayscale

../../../_images/a4.png
../../../_images/a8_a.png

option alpha

A2

../../../_images/picto.png

option grayscale

../../../_images/a2.png
../../../_images/a8_a.png

option alpha

A1

../../../_images/picto.png

option grayscale

../../../_images/a1.png
../../../_images/a8_a.png

option alpha

C4

../../../_images/grayscale.png ../../../_images/c4.png

C2

../../../_images/grayscale.png ../../../_images/c2.png

C1

../../../_images/grayscale.png ../../../_images/c1.png

AC44

../../../_images/grayscale_t.png ../../../_images/ac44.png

AC22

../../../_images/grayscale_t.png ../../../_images/ac22.png

AC11

../../../_images/grayscale_t.png ../../../_images/ac11.png

ARGB1565_RLE

../../../_images/transparent.png ../../../_images/argb1555.png

A8_RLE

../../../_images/picto.png

option grayscale

../../../_images/a8.png
../../../_images/a8_a.png

option alpha

Usage Advice

  • When the image is rarely used, or when there is little Flash and enough RAM: embed the image in its original compressed format (PNG or JPG for instance).

  • For an opaque image: RGB565 is usually sufficient.

  • For a transparent image: ARGB4444 is usually sufficient.

  • For a transparent image that contains only shape(s) with horizontal or vertical edges:

    • ARGB1555 may be interesting to have more colors,

    • for a smaller footprint if the image matches the RLE rule, ARGB1565_RLE is best.

  • For a pictogram to colorize:

    • A4 is usually sufficient,

    • A8 may be necessary for pictograms with long gradients,

    • for a smaller footprint if the image matches the RLE rule, A8_RLE is best.

  • For BSP with a GPU, choose a format compatible with the GPU (all formats may not be available),

    • ARGB formats: choose between non-premultiplied formats and premultiplied formats (suffixed with _PRE),

    • Ax formats (pictogram): all bits-per-pixel values may not be available.

    • be careful about the color components position (A-R-G-B versus R-G-B-A for instance),

    • avoid formats Cx, ACxx and xxx_RLE, which are not compatible with a GPU.

Caching Generated Images

Images converted using the Image Generator can be cached so that they are not rebuilt every time the application is launched. Doing so can significantly speed up the application build phase.

The cache is enabled by default. It may be disabled by setting the Application option ej.microui.imageConverter.disableCache to true.

The Image Generator obeys several rules when choosing whether an image should be converted.

  • If the cache is disabled, all images are generated every time the application is launched.

  • All images will be regenerated if the application is launched using another VEE port and the new VEE port uses a different Image Generator or another set of Image Generator plugins.

  • If the generated image does not exist, it will be generated.

  • If the source image has been modified since the last time it was converted, the image will be regenerated.

  • The image will be regenerated if the destination format has been modified in the images.list file.

Cached images are stored in .cache/images, which is located in the application output folder. You may delete this directory to force the generation of all images in your application. An image that was previously generated but is no longer listed in the *.images.list files when the application is launched will be deleted from the cache directory.

Warning

When testing an Image Generator extension project, the image cache is automatically disabled.

External Images

To fetch immutable images from external memory, the application must pre-register the external Image resources. The management of this kind of image may be different than the internal images and may require some allocations in the Images Heap. For more details about the external image management, refers to the VEE Port Guide chapter External Resource.

Image Generator Error Messages

These errors can occur while preprocessing images.

Static Image Generator Error Messages

ID

Type

Description

0

Error

The image generator has encountered an unexpected internal error.

1

Error

The images list file has not been specified.

2

Error

The image generator cannot create the final, raw file.

3

Error

The image generator cannot read the images list file. Make sure the system allows reading of this file.

4

Warning

The image generator has found no image to generate.

5

Error

The image generator cannot load the images list file.

6

Warning

The specified image path is invalid: The image will be not converted.

7

Warning

There are too many or too few options for the desired format.

8

Error

The display format is not generic; a MicroUIRawImageGeneratorExtension implementation is required to generate the MicroUI raw image.

9

Error

The image cannot be read.

10

Error

The image generator has encountered an unexpected internal error (invalid endianness).

11

Error

The image generator has encountered an unexpected internal error (invalid bpp).

12

Error

The image generator has encountered an unexpected internal error (invalid display format).

13

Error

The image generator has encountered an unexpected internal error (invalid pixel layout).

14

Error

The image generator has encountered an unexpected internal error (invalid output folder).

15

Error

The image generator has encountered an unexpected internal error (invalid memory alignment).

16

Error

The input image format and / or the ouput format are not managed by the image generator.

17

Error

The image has been already loaded with another output format.

Mutable Images

Overview

Unlike immutable images, mutable images are graphical resources that can be created and modified at runtime. The application can draw into such images using the Painter classes with the image’s Graphics Context as the destination. Mutable images can be created with a call to constructor ej.microui.display.BufferedImage().

BufferedImage image = new BufferedImage(320,  240);
GraphicsContext g = image.getGraphicsContext();
g.setColor(Colors.BLACK);
Painter.fillRectangle(g, 0, 0, 320, 240);
g.setColor(Colors.RED);
Painter.drawHorizontalLine(g, 50, 50, 100);
image.close();

Display Format

By default, the output format of a BufferedImage matches the display’s pixel organization (layout, depth, etc.). The algorithms used to draw in such an image are the same as those used on the display (for footprint purposes). The algorithm cannot draw transparent pixels since the display back buffer is opaque.

In addition, GraphicsContext.setColor() does not consider the alpha channel and only accepts RGB values. The given color value is interpreted as a 24-bit RGB color, where the high-order byte is ignored, and the remaining bytes contain the red, green, and blue channels, respectively.

Other Formats

It is also possible to create a buffered image with another format using the constructor with the format parameter.

The other formats than the display one are not supported by MicroUI. But a VEE port can manage one or more formats (see Destination Format).

Depending on the format, the transparency may be supported.

Images Heap

The image heap is used to allocate the pixel data of:

  • Mutable images (i.e. BufferedImage instances).

  • Immutable images decoded at runtime, typically a PNG: the heap is used to store the decoded image and the runtime decoder’s temporary buffers, required during the decoding step. After the decoding step, all the temporary buffers are freed. Note that the size of the temporary buffers depends on the decoder and on the original image itself (compression level, pixel encoding, etc.).

  • Immutable images which are not byte-addressable, such as images opened with an input stream (i.e. ResourceImage instances).

  • Immutable images which are byte-addressable but converted to a different output format (i.e. ResourceImage instances).

In other words, every image which cannot be retrieved using ej.microui.display.Image.getImage() is saved on the image heap.

The size of the images heap can be configured with the ej.microui.memory.imagesheap.size property.

Warning

A ResourceImage allocated on the images heap must be closed manually by the application (ResourceImage.close()); otherwise, a memory leak will occur on the images heap.

For more details about the images heap implementation, refers to this chapter in the VEE Port Guide.