Bitmap control

📘

Source code

Please see the UgBitmapDemo project for the source code created in this chapter. See Installing examples for information on how to download the examples. The URL is here for direct access is https://github.com/scadedoc/UgExamples/tree/master/UgSqlLiteSwift

Using the bitmap control, you can display bitmaps sourced from within the app or dynamically downloaded from the internet.

As with all of our controls, the controls represent a wrapper around the native controls and expose a subset of its functionality to user:

  • We support the following formats : PNG, SVG, JPG
  • We support SVG based scaling of the bitmap

SCDWidgetsBitmap

Attribute NameAttribute TypeAttribute MeaningExample
contentString!Field to store the actual image data that you want to displayBinary data
urlString!Relative path to the source of the image. Make sure you specify the correct path. It starts with the name of the resource folder followed by the image name.

You can only specify relative URLs that are local to the app directory structure. External URLs such as http:\...\myimage.png are currently not supported.
Correct
res/dog.png

Wrong:
/Appname/res/dog.png
/res/dog/png
* http:\...\mydog.png
isContentPriorityBoolDefines which inbound source is used to display the image
False, i.e. image data is retrieved using information in url field
True, i.e. image data is taken from the content field

Static display of images from within the app

To use a bitmap from within the app, just drag and drop the bitmap control onto the page and then select the image you want to display using the source field:

Dynamically assigning images sourced from within the app

Alternatively, you can set the image dynamically using code. It's easy but:

  • make sure you specify the path in the url field correctly. It's /<image.png|jpg|svg>
  • make sure you set the isContentPriority to false
import ScadeKit

class MainPageAdapter: SCDLatticePageAdapter {

	// page adapter initialization
	override func load(_ path: String) {		
		super.load(path)
		
		// get reference to second bitmap and set bitmap
		if let bc2 = self.page!.getWidgetByName("bitmap2") as? SCDWidgetsBitmap {
			bc2.url = "res/dog2.jpg"
			bc2.isContentPriority = false
		}
	}
}

Downloading and displaying images

To use images that don't exist on the app yet, we use the SCDNetworkRequest and SCDNetworkResponse objects to download the data:

  • set the content field with the raw image data received from the network call
  • make sure you set the isContentPriority to true
import ScadeKit

class MainPageAdapter: SCDLatticePageAdapter {

	// page adapter initialization
	override func load(_ path: String) {		
		super.load(path)
		
		// get reference to second bitmap and set bitmap
		if let bc2 = self.page!.getWidgetByName("bitmap2") as? SCDWidgetsBitmap {
			bc2.url = "res/dog2.jpg"
			bc2.isContentPriority = false
		}
		
		if let bc3 = self.page!.getWidgetByName("bitmap3") as? SCDWidgetsBitmap {
			let externalurl = "https://s3.amazonaws.com/scade.io/demo/documentation/dog3.jpg"
			let request = SCDNetworkRequest()
			request.url = externalurl
			if let response = request.call() {
				bc3.content = response.body!
				bc3.isContentPriority = true
			}
		}
		
	}
}

Use data binding to specify image to display

The quickest, most elegant way is to use the data mapping capability to specify which image to display:

  • specify a attribute imageUrl (use dynamic var)
  • create a helper variable falseValue of type Bool that you set to False
  • set the name of the image depending on the logic of the app. For now, we just set it to "res/dog.png" in the init method.

We use a new page to demo this binding feature. We named the page BindingAndScalePage.page and added toolbars to both pages:

import ScadeKit

class BindingAndScalePagePageAdapter: SCDLatticePageAdapter {

	dynamic var imageUrl:String 
	var falseValue:Bool = false
	
	// page adapter initialization
	override func load(_ path: String) {		
		super.load(path)
		
		// adding main btn 
		let main = self.page!.getWidgetByName("itmMain") as! SCDWidgetsClickable
		main.onClick.append(SCDWidgetsEventHandler{_ in self.navigation!.go("main.page")})
	}
	
	override init() {
		// setting the image location
		self.imageUrl = "res/dog.jpg"
	}
}

Furthermore, map the imageUrl and falseValue attributes to the exposed bitmap control:

This could be your preferred way of dynamically assigning images. It minimizes the amount of lines of code you have to write and is a very elegant way of achieving the goal.

Setting the scaling factor

We support the ability to scale the images using the SVG attribute called preserveAspectRatio

📘

SVG preserveAspectRatio Demo

Use the following URL to access online demo of how the different values of preserveAspectRatio work here

http://unmatchedstyle.com/news/svg-and-the-preserveaspectratio-property.php

and here
https://sarasoueidan.com/demos/interactive-svg-coordinate-system/#CheatSheet

Here are the most often used values....

preserveAspectRatio valuePreview
xMidYMid meet
Scales uniformly but keeps ratio
xMidYMid slice
Scales uniformly as much as
necessary to cover viewpoint
xMaxYMaxSlice
Uses all the available space in X and Y direction

!! We will add the ability to set the value through the page editor shortly.