Technical Articles
Handling Images in SAP Build Apps
At a recent Code Jam, some of the participants were curious and wanted to know how to take an image with their phone and display in the app (even though it had nothing to do with our exercise 😺).
Then, a few days ago, I was building an application to show a generated barcode, and it wasn’t clear how to display the image.
Image from API (URL)
This is the simplest and probably something everyone knows how to do.
I did the following:
- Set the Source property of the Image component to the URL of my API.
In this example, I generated a barcode with a simple API URL. We could have made it into a formula so people could enter the barcode value and the barcode type.
https://barcode.orcascan.com/?type=code39&data=12345678901
This was the result:
It doesn’t make a difference if the URL is hardcoded to an image on the internet, or comes from an API call that returns a URL in the response, or from a simple API call (no headers, GET method) that returns an image like for baseball player headshot or the one above for generating barcodes.
Image from API (Stream)
But I had a different API, one that required a POST request and some headers, including an API key. This I could not do with the above method. So I asked one of my colleagues, Pekka Aaltonen, what to do and he was gracious to provide a simple script.
For this, I used a barcode-generating API, that requires a key, from Cloudmersive APIs.
I did the following:
- Created a page variable, MyImage, of type text.
- Set the Source property of the Image component to this variable.
- Added a JavaScript flow function, whose output would be set into MyImage.
- Added code to the JavaScript flow function to request the barcode and get the image as a stream.
The JavaScript flow function was set up with no inputs and a single output whose name was url of type text.
And this was the code:
const response = await fetch('https://testapi.cloudmersive.com/barcode/generate/upc-a', {
method: 'POST',
headers: {
Apikey: '<your API Key>',
'Content-Type': 'application/json'
},
body: '829576019311' // not json, but this is what the API expects despite the header
});
const blob = await response.blob();
const url = URL.createObjectURL(new Blob([blob]));
return [0, { url }];
This was the result:
You will have to create an account and supply an API key. We also could have made things more dynamic by letting the user enter a barcode value and then creating an input to the JavaScript flow function for the barcode value.
Image from API (Base64)
Many times images are converted to base64 text strings, so we must be able to handle these. Base64 is a way to encode binary data as text strings for channels that only reliably transmit text.
For this example, I will use the images supplied by Microsoft’s Northwind OData service within the Employee entity.
I did the following:
- Created an OData data resource to the Northwind, and enabled the Employees entity.
- Created a “single data record” data variable for this entity. For this example, I hardcoded employee 1.
- Set the Source property of the Image component to the following formula:
"data:image/png;base64," + SUBSTRING(data.Employees1.Photo, 104)​
The Northwind images have 104 extra characters at the beginning that you have to strip off (if you’re curious why, Google it).
This was the result:
Image from Phone
You want to to take a picture with your phone and display it in an Image component.
I did the following:
- Created a page variable called ImagePath of type Text → Image URL.
- Set the Source property of the Image component to this page variable.
- Added a button.
- To the button’s logic, added flow functions to take a picture (Take photo, a standard flow function) and to set our page variable. You will have to use the following formula to set the variable.
outputs["Take photo"].photoFile.path
Now, I can click the button, opening the camera interface on the phone.
I take a picture.
The picture now appears in the Image component.
Sending Images
For sending photos, I will not explain how to do but will give 2 examples from other people’s tutorials:
- Tutorial by Onno Bos. In this tutorial, Onno takes an image on the device and sends as a blob in an API to an AI service.
- Tutorial by Sergio Guerrero called Build Bros – Handling file upload via HTTP Request. In this tutorial, Sergio takes an image, converts to Base64, and uploads to AWS.
Asset Manager
If you have a lot of images you’ve made especially for your app, to displayed anywhere in the app, you can upload them to the Asset Manager, storing them in your app, and then use them in any Image component.
Go to the properties of any Image component (or any component that uses images, like a container, which uses images for its background). Click the Asset Manager button.
Then select images to upload.
Then, in any component with images, again select the Asset Manager button and select the image you want.
You can create folders in the Asset Manager to better organize the images.
Let me know if you have additional questions or if there are other things you do or want to do with images in SAP Build Apps.
Thank you for the course and thank you for this blog Daniel,
Was very challenging to explore at the moment!
Hi Daniel Wroblewski , indeed thanks for the many image handling tips.
Actually I have been using the base64 encoded image to blob conversion with Appgyver for quite some time: you may look up the use case here and the code there.
Worth mentioning is that
blob I use will result in a smaller size as compared to the PNG format. Which is convenient when it comes to storing the blobs in a external database or so....
my 2 cents; Piotr
Very interesting...
I liked the integration between Javascript, API URL and Base64 encoding.
I was familiar with Base64 encoding, QR Images from E-Invoice Implementation project for (Saudi Arabia) but i learned many tips from your blog.
Thanks for sharing Daniel .
About the asset manager part, I'm interested to know how to get the URL of one of those images dinamically.
Let' s say I upload 5 images, then I'd like to select one of them programmatically (via, a certain logic for example using either a formula or some JS code lines).
I want to get the corresponding image URL and use it to show the image in a image component.
A use case can be a list of large image list items where the image is dynamically picked (from one of the uploaded in the asset manager) accordingly a certain property value related to the corresponding object item.
I didn't find anything that allows to build a image URL contained in the asset manager.
Is it possibile to do that?
many thanks
Regards
Roberto