Skip to main content

Images

|

The images are represented in an abstract form which is not directly drawable on the UI. The responsible classes are Image, AbstractGeometryImage, LaneImage, SignpostImage, and RoadInfoImage.

These classes provide the following methods and properties:

  • uid: Gets the unique ID of the image. If two images are the same, then they have the same UID. This allows the user to optimize UI redraws and trigger an update only when the image changes.
  • isValid(): Verifies if the image data is valid. If the image is not valid, then asBitmap() and render() methods will return null or fail.
  • asBitmap(width, height): Returns an Android Bitmap which can be displayed on the UI using ImageView.setImageBitmap(). It returns null if the image is invalid.
  • render(bitmap): Renders the image into the provided IBitmap object. Returns error codes for validation.

Plain images

The Image class corresponds to plain (usually non-vector) images. These images have a recommended size and aspect ratio but can be resized to any dimension in order to be drawn (with possible loss of quality).

The user can instantiate an Image class:

  • Using the Image.produceWithDataBuffer() method which takes a DataBuffer containing the image data and an EImageFileFormat.
  • Using the Image.produceWithPath() method which takes a file path to an image file.
  • Using the ImageDatabase to retrieve predefined SDK images by ID.

Special images

The AbstractGeometryImage, LaneImage, SignpostImage, and RoadInfoImage classes correspond to vector images generated by the SDK based on internal data. They provide customizable options for rendering. They do not have a default size or aspect ratio.

The LaneImage, SignpostImage, and RoadInfoImage classes provide specialized asBitmap() methods that handle resizing automatically based on the image content. These images can also be configured with custom render settings for colors and appearance.

The particularities of each image type are presented in the table below:

ClassSize and aspect ratioCustomizable render optionsThe size of the bitmap returned by the asBitmap() methodsInstantiable by the user
ImageUsually fixed and retrievable via the size and aspectRatio properties.Not availableWill always render at the size specified by the user if provided, or the recommended size for the particular image otherwise.Yes, via the provided factory methods Image.produceWithDataBuffer() and Image.produceWithPath(). It can also be provided by the SDK.
AbstractGeometryImageGenerated by the SDK. Size and aspect ratio not retrievable.Yes, via AbstractGeometryImageRenderSettingsWill always render at the size specified by the user if provided, or the SDK default image size otherwise.No. Can only be provided by the SDK.
LaneImageGenerated by the SDK. Size and aspect ratio not retrievable.Yes, via LaneImageRenderSettingsReturns a Pair<Int, Bitmap?> where the first value is the actual width used (when width is 0, auto-calculated), and the second is the bitmap.No. Can only be provided by the SDK.
SignpostImageGenerated by the SDK. Size and aspect ratio not retrievable.Yes, via SignpostImageRenderSettingsReturns a Pair<Int, Bitmap?> where the first value is the actual width used (when width is 0, auto-calculated), and the second is the bitmap.No. Can only be provided by the SDK.
RoadInfoImageGenerated by the SDK. Size and aspect ratio not retrievable.Background color customizable via RgbaReturns a Pair<Int, Bitmap?> where the first value is the actual width used (when width is 0, auto-calculated), and the second is the bitmap.No. Can only be provided by the SDK.
Tip

For debugging purposes, image bitmaps can be saved to files or viewed directly on Android devices. You can use the Bitmap.compress() method to save bitmaps to PNG format for inspection during development.

Approaches

The different approaches for getting images as Android Bitmap objects from the SDK are illustrated below using the lane image contained within NavigationInstruction. The general principles are the same for all types of images.

Approach 1

val laneImage = instruction.laneImage
val bitmap = laneImage?.asBitmap(200, 100)

// Usage example
if (bitmap != null) {
// Successfully obtained lane image bitmap
imageView.setImageBitmap(bitmap)
} else {
// Handle error case
println("Failed to get lane image bitmap")
}

This approach is simple and straightforward, with minimal boilerplate code. However, it comes with a few limitations:

  • You don't have access to custom color settings for the lane image.
  • There is no way to retrieve the actual image size when using auto-sizing.
  • The image UID is not directly accessible through this method.

The asBitmap method returns null if the image is invalid.

Approach 2

val laneImage = instruction.laneImage
val (actualWidth, bitmap) = laneImage?.asBitmap(200, 100) ?: Pair(0, null)

// Get more data about the lane image
val uid = laneImage?.uid ?: 0L

This approach provides the actual width used when rendering the image, which is particularly useful for lane images that auto-calculate their width based on content.

The asBitmap method returns a Pair<Int, Bitmap?> where:

  • The first value is the actual width used (especially when you pass 0 for width to auto-calculate)
  • The second value is the rendered bitmap or null if invalid

You can efficiently use the image UID to optimize redraws by checking if the image has changed before re-rendering.

Approach 3

val laneImage = instruction.laneImage
val backgroundColor = Rgba(118, 99, 200, 255)
val activeColor = Rgba(255, 255, 255, 255)
val inactiveColor = Rgba(24, 33, 21, 255)

val (actualWidth, bitmap) = laneImage?.asBitmap(
200, 100,
backgroundColor,
activeColor,
inactiveColor
) ?: Pair(0, null)

// Get more data about the lane image
val uid = laneImage?.uid ?: 0L

This approach provides the greatest flexibility by allowing custom color configuration:

  • backgroundColor: The background color of the lane image
  • activeColor: Color for active/highlighted lanes
  • inactiveColor: Color for inactive/non-highlighted lanes

The returned Pair contains the actual dimensions and the rendered bitmap with your custom colors applied.

Approach 4 - Using GemUtilImages

val laneImage = instruction.laneImage
val backgroundColor = Rgba(118, 99, 200, 255)
val activeColor = Rgba(255, 255, 255, 255)
val inactiveColor = Rgba(24, 33, 21, 255)

val resultPair = SdkCall.execute {
GemUtilImages.asBitmap(
laneImage,
200,
100,
backgroundColor,
activeColor,
inactiveColor
)
}

val errorCode = resultPair?.first ?: -1
val bitmap = resultPair?.second

if (errorCode == 0 && bitmap != null) {
// Successfully obtained lane image bitmap
imageView.setImageBitmap(bitmap)
} else {
// Handle error case
println("Failed to get lane image, error code: $errorCode")
}

This approach uses the GemUtilImages utility class directly and provides error codes for more detailed error handling. The method returns a Pair<Int, Bitmap?> where the first value is an error code (0 for success) and the second is the bitmap.

This method should be called within SdkCall.execute for thread safety.

Working with Render Settings

Different image types provide customizable render settings to control their appearance:

Lane Image Settings

val laneRenderSettings = LaneImageRenderSettings().apply {
backgroundColor = Rgba(118, 99, 200, 255) // Purple background
activeColor = Rgba(255, 255, 255, 255) // White for active lanes
inactiveColor = Rgba(128, 128, 128, 255) // Gray for inactive lanes
}

// Use the settings when rendering
val (width, bitmap) = laneImage?.asBitmap(200, 100,
laneRenderSettings.backgroundColor,
laneRenderSettings.activeColor,
laneRenderSettings.inactiveColor
) ?: Pair(0, null)

Signpost Image Settings

val signpostSettings = SignpostImageRenderSettings().apply {
borderSize = 10 // Border size in pixels
borderRoundCorners = true // Use rounded corners
maxRows = 3 // Maximum rows of details
smallMode = false // Use large mode
}

// Apply settings when rendering signpost images
val (width, bitmap) = signpostImage?.asBitmap(300, 150) ?: Pair(0, null)

Abstract Geometry Image Settings

val geometrySettings = AbstractGeometryImageRenderSettings().apply {
activeInnerColor = Rgba(255, 255, 255, 255) // White inner active
activeOuterColor = Rgba(0, 0, 0, 255) // Black outer active
inactiveInnerColor = Rgba(128, 128, 128, 255) // Gray inner inactive
inactiveOuterColor = Rgba(64, 64, 64, 255) // Dark gray outer inactive
}

// Use custom colors for turn arrows
val turnBitmap = abstractGeometryImage?.asBitmap(80, 80,
geometrySettings.activeInnerColor,
geometrySettings.activeOuterColor,
geometrySettings.inactiveInnerColor,
geometrySettings.inactiveOuterColor
)

Common Use Cases

Displaying Lane Instructions

// From navigation instruction
val instruction: NavigationInstruction = // ... obtained from navigation
val laneImage = instruction.laneImage

// Display lane guidance with custom colors
laneImage?.let { image ->
val (actualWidth, bitmap) = image.asBitmap(
0, 60, // Auto-calculate width, 60px height
Rgba(30, 30, 30, 255), // Dark background
Rgba(0, 255, 0, 255), // Green for active lanes
Rgba(100, 100, 100, 255) // Gray for inactive lanes
)

if (bitmap != null) {
laneImageView.setImageBitmap(bitmap)
// Optionally adjust view width based on actualWidth
}
}

Displaying Turn Instructions

// From navigation instruction
val turnImage = instruction.nextTurnDetails?.abstractGeometryImage

turnImage?.let { image ->
val bitmap = image.asBitmap(80, 80,
Rgba(255, 255, 255, 255), // Active inner: white
Rgba(0, 0, 0, 255), // Active outer: black
Rgba(128, 128, 128, 255), // Inactive inner: gray
Rgba(64, 64, 64, 255) // Inactive outer: dark gray
)

if (bitmap != null) {
turnArrowImageView.setImageBitmap(bitmap)
}
}

Creating Custom Images

// Load an image from assets
val customImage = SdkCall.execute {
Image.produceWithPath("/path/to/image.png")
}

// Or from a data buffer
val imageData: ByteArray = // ... load your image data
val dataBuffer = DataBuffer().apply {
// Populate with image data
}
val customImage2 = Image.produceWithDataBuffer(dataBuffer, EImageFileFormat.Png)

// Convert to bitmap for display
val bitmap = customImage?.asBitmap(100, 100)

Using Predefined SDK Images

// Access predefined images from the SDK
val tollImage = ImageDatabase.tollImage
val ferryImage = ImageDatabase.ferryImage
val searchPin = ImageDatabase.searchResultsPin

// Convert to bitmaps for display
val tollBitmap = tollImage?.asBitmap(32, 32)
val ferryBitmap = ferryImage?.asBitmap(32, 32)