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

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 ../../../_images/a8_c.png
A4 ../../../_images/picto.png ../../../_images/a4.png
With 0x0000ff as color ../../../_images/a4_c.png
A2 ../../../_images/picto.png ../../../_images/a2.png
With 0x0000ff as color ../../../_images/a2_c.png
A1 ../../../_images/picto.png ../../../_images/a1.png
With 0x0000ff as color ../../../_images/a1_c.png
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 ../../../_images/a8.png

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.