Clinical Encounters is an immersive patient encounter experience whereby you are relying on an EHR framework to diagnose and treat a virtual patient. In order to achieve this, some integration of visuals alongside the text is necessary to create an informative patient case. Here, one of our programmers details how we’ve utilized images within Clinical Encounters.
Why Do We Need Images?
Images are something that can add value to almost any case. They offer users to upload custom content that could explain much more than words ever could. Think of MRI scans, x-rays, educational diagrams, example photos, healthy vs unhealthy comparisons, and many more examples. As they say, a picture is worth a thousand words. Not only can they be educational, but they act to spice up the case as well as keep it interesting and lively. So, with image integration, we hope to expand the flexibility of what case creators can show others while improving the case reading experience.
We give users the option to add images in several locations on numerous different tabs. Wherever we allow images to be added, we present users with the shown “Add Image” button. From there, they can select and add any image they have locally saved into their case. Clicking on previews of uploaded images also brings up a bigger version of the image.
Concerns With Handling These Images
Our main concerns were how to handle the image data storage, referencing images correctly, image file size, and which image formats we would allow.
Early on, we decided that the images would be stored separately from the XML that stores the rest of the case. Yet, since we use XML everywhere else, we wanted to keep the consistency and have chosen to store all images in their own XML file. This was chosen for a few reasons. It helped during development when we needed to parse through cases by hand to see where issues were being caused. This would have been a pain, to say the least, if we had to parse through the additional overhead from images as well. It also lets us handle the images separately if we ever want to since a case’s images are usually a good deal larger than the other saved data.
There are some downsides to keeping the images separate, such as having to manage two files instead of only one, but overall the pros outweigh cons.
The Biggest Struggle
The biggest difficulty with images came from keeping a reference to each image. The initial system gave each image a reference name based on where it could be found in the hierarchy. Each section, each tab, and each entry or sub-entry would have a unique name, so we used this information to construct a reference to the exact spot the image could be found. This worked well at first, but the biggest enemy to a system like this was the ability to rearrange entries.
Let’s look at an example. I have two images, one attached to the first entry on a tab and the second attached to the second. Now, each entry has a name which references its position and also the actual position. In the beginning, entry 0 would be in position 0 and entry 1 would be in position 1. Switch them and entry 0 is at position 1 and vice versa. When we save this tab, the images have to update their references to point to their new position or else they wouldn’t move with the rest of their entry.
Now, what if we rearrange the entries and then try to overwrite an image before saving the tab? Then we have to use the name of its parent entry instead of its position to figure out what to overwrite. Combine this with images within pinned quizzes, where images have an even more complex reference name – not to mention the additional complexities with setting up the reference – and you’ve got yourself a real mess to handle.
A New Referencing System
At this point we realized that the current system wasn’t cutting it, so we redid it. The new approach was to create a random, but unique reference name for each image and then store that alongside the rest of the case data. This way, when loading data into each tab, the software could see the reference ID of the image, look it up in the accompanying image dictionary, and load that image. To generate random names we used the GUID class, or more specifically, a string representation of a new GUID instance.
So now, instead of having the following reference to deal with and constantly update (PATIENT INTRO SECTION > PERSONAL INFO TAB > ENTRY: 0), it’s now (C6BF4B8884) and is kept alongside the rest of the data making it easy to find and load.
Overall, it was definitely worth switching over to this method as there have been hardly any problems since. Most of the issues with the other system never even came up while testing the new one. Image compression and data format are still being worked on today, but those issues will be tackled soon!