Image Generator

Principle

The Image Generator module is an off-board tool that generates image data that is ready to be displayed without needing additional runtime memory. The two main advantages of this module are:

  • A pre-generated image is already encoded in the format known by the Image Renderer (MicroEJ format) or by the VEE Port (custom binary format). The time to create an image is very fast and does not require any RAM (Image Loader is not used).
  • No extra support is needed (no runtime Image Decoder).

Functional Description

Image Generator Principle

Image Generator Principle

Process overview (see too Functional Description)

  1. The user defines, in a text file, the images to load.
  2. The Image Generator outputs a binary file for each image to convert.
  3. The raw files are embedded as (hidden) resources within the MicroEJ Application. The binary files’ data are linked into the FLASH memory.
  4. When the application creates a MicroUI Image object which targets a pre-generated image, the Image Engine has only to create a link from the MicroUI image object to the data in the FLASH memory. Therefore, the loading is very fast; only the image data from the FLASH memory is used: no copy of the image data is sent to the RAM first.
  5. When the MicroUI Image is no longer needed, it is garbage-collected by the VEE Port, which just deletes the useless link to the FLASH memory.

The image generator can run in two modes:

  • Standalone mode: the image to convert (input files) are standard (PNG, JPEG, etc.), the generated binary files are in MicroEJ format and do not depend on VEE Port characteristics or restrictions (see MicroEJ Format: Standard).
  • Extended mode: the image to convert (input files) may be custom, the generated binary files can be encoded in customized MicroEJ format (can depend on several VEE Port characteristics and restrictions, see MicroEJ Format: Display, GPU Format Support and MicroEJ Format: Custom) or the generated files are encoded in another format than MicroEJ format (binary format, see Binary Format).

Structure

The Image Generator module is constituted from several parts, the core part and services parts:

  • “Core” part: it takes an images list file as entry point and generates a binary file (no specific format) for each file. To read a file, it redirects the reading to the available service loaders. To generate a binary file, it redirects the encoding to the available service encoders.
  • “Service API” part: it provides some APIs used by the core part to load input files and to encode binary files. It also provides some APIs to customize the MicroEJ format.
  • “Standard input format loader” part: this service loads standard image files (PNG, JPEG, etc.).
  • “MicroEJ format generator” part: this service encodes an image in MicroEJ format.

Standalone Mode

The standalone Image Generator embeds all parts described above. By consequence, once installed in a VEE Port, the standalone image generator does not need any extended module to generate MicroEJ files from standard images files.

Extended Mode

To increase the capabilities of Image Generator, the extension must be built and added in the VEE Port. As described above this extension will be able to:

  • read more input image file formats,
  • extend the MicroEJ format with VEE Port characteristics,
  • encode images in a third-party binary format.

To do that the Image Generator provides some services to implement. This chapter explain how to create and include this extension in the VEE Port. Next chapters explain the aim of each service.

  1. Create a std-javalib project. The module name must start with the prefix imageGenerator (for instance imageGeneratorMyPlatform).

  2. Add the dependency:

    <dependency org="com.microej.pack.ui" name="ui-pack" rev="x.y.z">
       <artifact name="imageGenerator" type="jar"/>
    </dependency>
    

    Where x.y.z is the UI pack version used to build the VEE Port (minimum 13.0.0). The module.ivy should look like:

    <ivy-module version="2.0" xmlns:ea="http://www.easyant.org" xmlns:m="http://www.easyant.org/ivy/maven" xmlns:ej="https://developer.microej.com" ej:version="2.0.0">
    
       <info organisation="com.microej.microui" module="imageGeneratorMyPlatform" status="integration" revision="1.0.0">
          <ea:build organisation="com.is2t.easyant.buildtypes" module="build-std-javalib" revision="2.+"/>
       </info>
    
       <configurations defaultconfmapping="default->default;provided->provided">
          <conf name="default" visibility="public" description="Runtime dependencies to other artifacts"/>
          <conf name="provided" visibility="public" description="Compile-time dependencies to APIs provided by the VEE Port"/>
          <conf name="documentation" visibility="public" description="Documentation related to the artifact (javadoc, PDF)"/>
          <conf name="source" visibility="public" description="Source code"/>
          <conf name="dist" visibility="public" description="Contains extra files like README.md, licenses"/>
          <conf name="test" visibility="private" description="Dependencies for test execution. It is not required for normal use of the application, and is only available for the test compilation and execution phases."/>
       </configurations>
    
       <publications/>
    
       <dependencies>
          <dependency org="com.microej.pack.ui" name="ui-pack" rev="[UI Pack version]">
             <artifact name="imageGenerator" type="jar"/>
          </dependency>
       </dependencies>
    </ivy-module>
    
  3. Create the folder META-INF/services in source folder src/main/resources (this folder will be filled in later).

  4. When a service is added (see next chapters), build the easyant project.

  5. Copy the generated jar: target~/artifacts/imageGeneratorMyPlatform.jar in the VEE Port configuration project folder: MyPlatform-configuration/dropins/tools/

  6. Rebuild the platform.

Advanced: Test the Extension Project

To quickly test an extension project without rebuilding the VEE Port or manually exporting the project, add the Application Option ej.imagegenerator.extension.project to the absolute path of an Image Generator Extension project (e.g. c:\mycompany\myimagegeneratorextension). The Image Generator will use the specified Image Generator Extension project instead of the one included in the VEE Port. This feature is useful for locally testing certain changes in the Image Generator Extension project.

-Dej.imagegenerator.extension.project=${project_loc:myimagegeneratorextension}

Warning

This feature only works if the VEE Port has been built with the Image Generator module enabled.

The VEE Port will not actually contain the changes until a new VEE Port is built: the VEE Port dropins folder must be updated after any changes to the Image Generator Extension project.

Warning

Using this feature automatically disables the image cache.

Service Image Loader

The standalone Image Generator is not able to load all images formats, for instance SVG format. The service loader can be used to add this feature in order to generate an image file in MicroEJ format. There are two ways to populate the service loader: create a custom implementation of com.microej.tool.ui.generator.MicroUIRawImageGeneratorExtension or javax.imageio.spi.ImageReaderSpi.

MicroUIRawImageGeneratorExtension

This service allows to add a custom image reader.

  1. Open image generator extension project.
  2. Create an implementation of interface com.microej.tool.ui.generator.MicroUIRawImageGeneratorExtension.
  3. Create the file META-INF/services/com.microej.tool.ui.generator.MicroUIRawImageGeneratorExtension and open it.
  4. Note down the name of created class, with its package and classname.
  5. Rebuild the image generator extension, copy it in VEE Port configuration project (dropins/tools/) and rebuild the VEE Port (see above).

Note

The class com.microej.tool.ui.generator.BufferedImageLoader already implements the interface. This implementation is used to load standard images. It can be sub-classed to add some behavior.

ImageReaderSpi

This extension is part of AWT ImageIO. By default, the ImageIO class only manages the standard image formats JPG, PNG, BMP and GIF. It allows to add some image readers by adding some implementations of the service javax.imageio.spi.ImageReaderSpi.

Since UI Pack 13.2.0, the Image Generator automatically includes new image decoders (new ImageIO services, see the class com.microej.tool.ui.generator.BufferedImageLoader), compiled in JAR files that follow this convention:

  1. The JAR contains the service declaration /META-INF/services/javax.imageio.spi.ImageReaderSpi,
  2. The JAR filename’s prefix is imageio-,
  3. The JAR location is the VEE Port configuration project’s dropins/tools/ directory.

Note

The same JAR is used by the Image Generator and by the Front Panel.

Customize MicroEJ Standard Format

As mentioned above (MicroEJ Format: Display and GPU Format Support), the MicroEJ format can be extended by notions specific to the VEE Port (and often to the GPU the VEE Port is using). The generated file stays a MicroEJ file format, usable by the Image Renderer. Additionally, the file becomes compatible with the VEE Port constraints.

  1. Open image generator extension project.
  2. Create a subclass of com.microej.tool.ui.generator.BufferedImageLoader (to be able to load standard images) or create an implementation of interface com.microej.tool.ui.generator.MicroUIRawImageGeneratorExtension (to load custom images).
  3. Override method convertARGBColorToDisplayColor(int) if the VEE Port’s display pixel encoding is not standard (see Pixel Structure).
  4. Override method getStride(int) if a padding must be added after each line.
  5. Override method getOptionalHeader() if an additional header must be added between the MicroEJ file header and pixels array. The header size is also used to align image memory address (custom header is aligned on its size).
  6. Create the file META-INF/services/com.microej.tool.ui.generator.MicroUIRawImageGeneratorExtension and open it.
  7. Note down the name of created class, with its package and classname.
  8. Rebuild the image generator extension, copy it in VEE Port configuration project and rebuild the VEE Port (see above).

If the only constraint is the pixels array alignment, the Image Generator extension is not useful:

  1. Open VEE Port configuration file display/display.properties.
  2. Add the property imageBuffer.memoryAlignment.
  3. Build again the VEE Port.

This alignment will be used by the Image Generator and also by the Image Loader.

VEE Port MicroEJ Custom Format

The Image Generator does not yet provide a service for generating the MicroEJ Format: Custom. A custom image can only be created at runtime, see Buffered Image.

VEE Port Binary Format

The Image Generator can generate a binary file compatible with the VEE Port (and not with the Image Renderer). This is very useful when a VEE Port features a foundation library that can use other kinds of images than the MicroUI library. The binary file can be encoded according to the user’s options in the images list file.

  1. Open image generator extension project.
  2. Create an implementation of the interface com.microej.tool.ui.generator.ImageConverter.
  3. Create the file META-INF/services/com.microej.tool.ui.generator.ImageConverter and open it.
  4. Note the name of the created class, with its package and class name.
  5. Rebuild the image generator extension, copy it into the VEE Port configuration project, and rebuild the VEE Port (see above).

The binary file can have two kinds of formats (see the API OutputFileType getType()):

  • A simple resource: the binary output file is embedded as a resource; the application (or the library) can retrieve the file by using an API like getResourceAsStream().
  • An immutable file: the output file contains one or several immutable objects; the application (or the library) can retrieve the objects by using the Beyond Profile (BON) library.

Configuration File

The Image Generator uses a configuration file (also called the “list file”) for describing images that need to be processed. The list file is a text file in which each line describes an image to convert. The image is described as a resource path, and should be available from the application classpath.

Note

The list file must be specified in the application launcher (see Standalone Application Options). However, all the files in the application classpath with suffix .images.list are automatically parsed by the Image Generator tool.

Each line can add optional parameters (separated by a ‘:’) which define and/or describe the output file format (raw format). When no option is specified, the image is not converted and embedded as well.

Note

See Configuration File to understand the list file grammar.

  • MicroEJ standard output format: to encode the image in a standard MicroEJ format, specify the MicroEJ format:

    Standard Output Format Examples
    image1:ARGB8888
    image2:RGB565
    image3:A4
    
  • MicroEJ “Display” output format: to encode the image in the same format as the display (generic display or custom display, see Pixel Structure), specify display as output format:

    Display Output Format Example
    image1:display
    
  • MicroEJ “GPU” output format: this format declaration is identical to standard format. It is a format that is also supported by the GPU.

    GPU Output Format Examples
    image1:ARGB8888
    image2:RGB565
    image3:A4
    
  • MicroEJ ARGB1565_RLE output format (formerly RLE1): to encode the image in ARGB1565_RLE format, specify ARGB1565_RLE as output format:

    ARGB1565_RLE Output Format Example
    image1:ARGB1565_RLE
    image1:RLE1 # Deprecated
    
  • Without Compression: to keep original file, do not specify any format:

    Unchanged Image Example
    image1
    
  • Binary format: to encode the image in a format only known by the VEE Port, refer to the VEE Port documentation to know which format are available.

    Binary Output Format Example
    image1:XXX
    

Linker File

In addition to images binary files, the Image Generator module generates a linker file (*.lscf). This linker file declares an image section called .rodata.images. This section follows the next rules:

  • The files are always listed in same order between two application builds.
  • The section is aligned on the value specified by the Display module property imageBuffer.memoryAlignment (32 bits by default).
  • Each file is aligned on section alignment value.

External Resources

The Image Generator manages two configuration files when the External Resources Loader is enabled. The first configuration file lists the images which will be stored as internal resources with the MicroEJ Application. The second file lists the images the Image Generator must convert and store in the External Resource Loader output directory. It is the BSP’s responsibility to load the converted images into an external memory.

  • Refer to the chapter Images to have more details how to use this kind of resources.
  • Refer to the chapter External Resource to have more details how the Image Engine manages this kind of resources.

Installation

The Image Generator is an additional module for the MicroUI library. When the MicroUI module is installed, also install this module in order to be able to target pre-generated images.

In the VEE Port configuration file, check UI > Image Generator to install the Image Generator module. When checked, the properties file imageGenerator/imageGenerator.properties is required to specify the Image Generator extension project. When no extension is required (standalone mode only), this property is useless.

Use

The MicroUI Image APIs are available in the class ej.microui.display.Image ant its subclasses. There are no specific APIs that use a pre-generated image. When an image has been pre-processed, the MicroUI Image APIs getImage and loadImage will get/load the images.

Refer to the chapter Standalone Application Options (Libraries > MicroUI > Image) for more information about specifying the image configuration file.