I have been struggling through making Base64 images work properly in various areas of a job, so seeing as there is no clear information on how to do this, I thought I would make a post to preserve the info I have accumulated.
Encoding an image to save in a Database
I am using a device that sends me Image data on OPC-UA, so my data will come from a different system than most people will use.
When I get an image, I have a python script in my gateway that does the following:
import base64 logger = system.utilities.getLogger("logger") image = <my-image-data> #Convert file to base64 string imageBytes = ''.join(map(lambda x: chr(x % 256), image)) b64image = base64.b64encode(imageBytes) #Send to DB try: system.db.runPrepUpdate("INSERT INTO images (image) VALUES (?)", [b64image],database=Database) except: logger.info("Barcode Reader Database Insert Failed")
My database table is simply two columns, an index 'id' which is an AUTO_INCREMENT PRIMARY KEY, and 'image' which is a MEDIUMTEXT
Depending how your image data comes into python, you may have either an array of Java.lang.Short, and you need this code above.
If you have an array of bytes, you can skip to:
b64image = base64.b64encode(imageBytes)
and just set imageBytes to your image data.
If you look in your database, you should have soem nice large simple strings in the 'image' column.
Using the image in Perspective
In Perspective, the image data is relatively easy to use.
Make a named query with the following SQL:
SELECT image from images where id = :image
Add a parameter of type Int4 to the query with the name "image"
Test the query works and returns the string from the database when given a correct ID as a parameter.
Make a page and drag into the page an "Image" component from the "Perspective Components"
Name the image component "Image"
Bind PROPS->source to a "Query" and select the named query you just made.
Add a valid ID to the parameters
Add the following script transform to the binding:
def transform(self, value, quality, timestamp): b64Image = "data:image/jpeg;base64,%s"%value return b64Image
The image should now work correctly and display the image you selected.
You may need to change the "data:image/jpeg" to your image type.
Making a Download Button
Drag a button component from the "Perspective Components" onto the page.
Open up the Event Configuration and add a Script to "onClick"
Enter the method below:
def runAction(self, event): from com.inductiveautomation.ignition.common import Base64 image64 = self.getSibling("Image").props.source image = Base64.decode(image64) data = image system.perspective.download("image.jpg", data)
When you click on the button, the image should download to your client and be usable as a normal image file.
Using the image in Reports
Create a Report and add a query datasource using the named query you used earlier.
Set the Data Key to "queryDataKey"
Add a Script Datasource under it with the below code:
def updateData(data, sample): from com.inductiveautomation.ignition.common import Base64 image64 = data['queryDataKey'].getCoreResults().getValueAt(0, 0) image = Base64.decode(image64) data['image']=image
Drag an image into the report in the Design tab, and drag the 'image' key from Data Sources into the image ImageShape->Key property.
Open the Preview tab, and the image should now be displayed.