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, thenasBitmap()andrender()methods will returnnullor fail.asBitmap(width, height): Returns an AndroidBitmapwhich can be displayed on the UI usingImageView.setImageBitmap(). It returnsnullif the image is invalid.render(bitmap): Renders the image into the providedIBitmapobject. 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 aDataBuffercontaining the image data and anEImageFileFormat. - Using the
Image.produceWithPath()method which takes a file path to an image file. - Using the
ImageDatabaseto 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:
| Class | Size and aspect ratio | Customizable render options | The size of the bitmap returned by the asBitmap() methods | Instantiable by the user |
|---|---|---|---|---|
Image | Usually fixed and retrievable via the size and aspectRatio properties. | Not available | Will 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. |
AbstractGeometryImage | Generated by the SDK. Size and aspect ratio not retrievable. | Yes, via AbstractGeometryImageRenderSettings | Will 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. |
LaneImage | Generated by the SDK. Size and aspect ratio not retrievable. | Yes, via LaneImageRenderSettings | Returns 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. |
SignpostImage | Generated by the SDK. Size and aspect ratio not retrievable. | Yes, via SignpostImageRenderSettings | Returns 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. |
RoadInfoImage | Generated by the SDK. Size and aspect ratio not retrievable. | Background color customizable via Rgba | Returns 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. |
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
- Kotlin
- Java
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")
}
LaneImage laneImage = instruction.getLaneImage();
Bitmap bitmap = null;
if (laneImage != null) {
bitmap = laneImage.asBitmap(200, 100);
}
// Usage example
if (bitmap != null) {
// Successfully obtained lane image bitmap
imageView.setImageBitmap(bitmap);
} else {
// Handle error case
System.out.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
- Kotlin
- Java
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
LaneImage laneImage = instruction.getLaneImage();
int actualWidth = 0;
Bitmap bitmap = null;
if (laneImage != null) {
Pair<Integer, Bitmap> result = laneImage.asBitmap(200, 100);
if (result != null) {
actualWidth = result.first;
bitmap = result.second;
}
}
// Get more data about the lane image
long uid = laneImage != null ? laneImage.getUid() : 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
- Kotlin
- Java
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
LaneImage laneImage = instruction.getLaneImage();
Rgba backgroundColor = new Rgba(118, 99, 200, 255);
Rgba activeColor = new Rgba(255, 255, 255, 255);
Rgba inactiveColor = new Rgba(24, 33, 21, 255);
int actualWidth = 0;
Bitmap bitmap = null;
if (laneImage != null) {
Pair<Integer, Bitmap> result = laneImage.asBitmap(
200, 100,
backgroundColor,
activeColor,
inactiveColor
);
if (result != null) {
actualWidth = result.first;
bitmap = result.second;
}
}
// Get more data about the lane image
long uid = laneImage != null ? laneImage.getUid() : 0L;
This approach provides the greatest flexibility by allowing custom color configuration:
backgroundColor: The background color of the lane imageactiveColor: Color for active/highlighted lanesinactiveColor: 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
- Kotlin
- Java
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")
}
LaneImage laneImage = instruction.getLaneImage();
Rgba backgroundColor = new Rgba(118, 99, 200, 255);
Rgba activeColor = new Rgba(255, 255, 255, 255);
Rgba inactiveColor = new Rgba(24, 33, 21, 255);
Pair<Integer, Bitmap> resultPair = SdkCall.execute(() ->
GemUtilImages.asBitmap(
laneImage,
200,
100,
backgroundColor,
activeColor,
inactiveColor
)
);
int errorCode = resultPair != null ? resultPair.first : -1;
Bitmap bitmap = resultPair != null ? resultPair.second : null;
if (errorCode == 0 && bitmap != null) {
// Successfully obtained lane image bitmap
imageView.setImageBitmap(bitmap);
} else {
// Handle error case
System.out.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
- Kotlin
- Java
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)
LaneImageRenderSettings laneRenderSettings = new LaneImageRenderSettings();
laneRenderSettings.setBackgroundColor(new Rgba(118, 99, 200, 255)); // Purple background
laneRenderSettings.setActiveColor(new Rgba(255, 255, 255, 255)); // White for active lanes
laneRenderSettings.setInactiveColor(new Rgba(128, 128, 128, 255)); // Gray for inactive lanes
// Use the settings when rendering
int width = 0;
Bitmap bitmap = null;
if (laneImage != null) {
Pair<Integer, Bitmap> result = laneImage.asBitmap(200, 100,
laneRenderSettings.getBackgroundColor(),
laneRenderSettings.getActiveColor(),
laneRenderSettings.getInactiveColor()
);
if (result != null) {
width = result.first;
bitmap = result.second;
}
}
Signpost Image Settings
- Kotlin
- Java
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)
SignpostImageRenderSettings signpostSettings = new SignpostImageRenderSettings();
signpostSettings.setBorderSize(10); // Border size in pixels
signpostSettings.setBorderRoundCorners(true); // Use rounded corners
signpostSettings.setMaxRows(3); // Maximum rows of details
signpostSettings.setSmallMode(false); // Use large mode
// Apply settings when rendering signpost images
int width = 0;
Bitmap bitmap = null;
if (signpostImage != null) {
Pair<Integer, Bitmap> result = signpostImage.asBitmap(300, 150);
if (result != null) {
width = result.first;
bitmap = result.second;
}
}
Abstract Geometry Image Settings
- Kotlin
- Java
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
)
AbstractGeometryImageRenderSettings geometrySettings = new AbstractGeometryImageRenderSettings();
geometrySettings.setActiveInnerColor(new Rgba(255, 255, 255, 255)); // White inner active
geometrySettings.setActiveOuterColor(new Rgba(0, 0, 0, 255)); // Black outer active
geometrySettings.setInactiveInnerColor(new Rgba(128, 128, 128, 255)); // Gray inner inactive
geometrySettings.setInactiveOuterColor(new Rgba(64, 64, 64, 255)); // Dark gray outer inactive
// Use custom colors for turn arrows
Bitmap turnBitmap = null;
if (abstractGeometryImage != null) {
turnBitmap = abstractGeometryImage.asBitmap(80, 80,
geometrySettings.getActiveInnerColor(),
geometrySettings.getActiveOuterColor(),
geometrySettings.getInactiveInnerColor(),
geometrySettings.getInactiveOuterColor()
);
}
Common Use Cases
Displaying Lane Instructions
- Kotlin
- Java
// 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
}
}
// From navigation instruction
NavigationInstruction instruction = // ... obtained from navigation
LaneImage laneImage = instruction.getLaneImage();
// Display lane guidance with custom colors
if (laneImage != null) {
Pair<Integer, Bitmap> result = laneImage.asBitmap(
0, 60, // Auto-calculate width, 60px height
new Rgba(30, 30, 30, 255), // Dark background
new Rgba(0, 255, 0, 255), // Green for active lanes
new Rgba(100, 100, 100, 255) // Gray for inactive lanes
);
if (result != null && result.second != null) {
int actualWidth = result.first;
Bitmap bitmap = result.second;
laneImageView.setImageBitmap(bitmap);
// Optionally adjust view width based on actualWidth
}
}
Displaying Turn Instructions
- Kotlin
- Java
// 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)
}
}
// From navigation instruction
AbstractGeometryImage turnImage = null;
if (instruction.getNextTurnDetails() != null) {
turnImage = instruction.getNextTurnDetails().getAbstractGeometryImage();
}
if (turnImage != null) {
Bitmap bitmap = turnImage.asBitmap(80, 80,
new Rgba(255, 255, 255, 255), // Active inner: white
new Rgba(0, 0, 0, 255), // Active outer: black
new Rgba(128, 128, 128, 255), // Inactive inner: gray
new Rgba(64, 64, 64, 255) // Inactive outer: dark gray
);
if (bitmap != null) {
turnArrowImageView.setImageBitmap(bitmap);
}
}
Creating Custom Images
- Kotlin
- Java
// 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)
// Load an image from assets
Image customImage = SdkCall.execute(() ->
Image.produceWithPath("/path/to/image.png")
);
// Or from a data buffer
byte[] imageData = // ... load your image data
DataBuffer dataBuffer = new DataBuffer();
// Populate with image data
Image customImage2 = Image.produceWithDataBuffer(dataBuffer, EImageFileFormat.Png);
// Convert to bitmap for display
Bitmap bitmap = null;
if (customImage != null) {
bitmap = customImage.asBitmap(100, 100);
}
Using Predefined SDK Images
- Kotlin
- Java
// 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)
// Access predefined images from the SDK
Image tollImage = ImageDatabase.getTollImage();
Image ferryImage = ImageDatabase.getFerryImage();
Image searchPin = ImageDatabase.getSearchResultsPin();
// Convert to bitmaps for display
Bitmap tollBitmap = tollImage != null ? tollImage.asBitmap(32, 32) : null;
Bitmap ferryBitmap = ferryImage != null ? ferryImage.asBitmap(32, 32) : null;