Every now and then a question arises that spawns enough discussion that I think it is worthy of a blog post. The topic of discussion around JMP's virtual water cooler this time is the idea of including an image inside a JSL script. A similar discussion arose not long ago and prompted me to write a blog post called How to Add an Image to a Graph in JMP 9. But this time the initial question, and subsequent discussion, specifically asked about embedding the image in the script such that the script is not dependent on an external image file. An email thread started on Tuesday, and on Wednesday it found its way into my inbox. By Friday, I was still seeing more responses to the thread. I decided if there was that much interest within JMP, certainly there would be some interest throughout the JMP user community.
So can you embed an image within a JSL script so that the original image file is no longer necessary? The answer is, of course, yes. (If it was no I wouldn't be writing this blog post!) Ironically, the whole discussion about embedding images was going on at the same time I was writing my last blog post, Using images to add context to your data. So let's start where that one left off.
In that blog post, I used a JMP data table to generate a bivariate plot. The graph included arrows showing wind speed and direction. I then added an image to the graph. The image was a map of the area where the wind readings took place -- around Lake Michigan. If I wanted to save the graph, I could use the little-red-triangle (lrt) and select Script->Save Script to Script Window. This would write the JSL necessary to reproduce the entire graph. If I do that, I will see the following code. (This is only a portion of the actual code.)
Add Image(
Set Blob(
Char To Blob(
"625799eJM//9WNs7G2+0s6euR1e ... Ix0RcMtzpWCTfj/AXh1fKw=",
"base64compressed"
),
"png"
),
Bounds(
Left( -90.96 ),
Right( -84.02 ),
Top( 44.97 ),
Bottom( 39.04 )
)
),
If you read How to Add an Image to a Graph in JMP 9, you will recognize the Add Image command. But in that example, I used a file reference, which meant that the JSL was dependent on an external image file. In this example, instead of a file reference, we are using a blob. The blob is a long string of character data that has been compressed using base64 compression. This is the smallest way to store an image as pixel data inside of a script. By the way, the ... in the middle of the string is to show that the majority of the character string has been removed for brevity. The actual string is much longer than what I've shown here. In addition to the compressed character data, the image type is also written out. This is so that when the script is read in, JMP knows how to interpret the character data stored in the blob. The nice thing about this is that I can generate the graph I want and then use Save Script to Script Window to get JMP to generate the compressed character data for me. I don't have to figure out how to do it myself. Nice!
At this point you might be wondering how big the script file is now. Well, in my case, the script without the image embedded is 1 KB. The image file is a PNG file and it is 26 KB. So the two files combined would be 27 KB. If I embed the image in the script file and save it to disk, the script file is now 34 KB. So the script containing the image is larger than the two individual files combined. But, I have to admit, I was surprised that it wasn't much larger. The PNG file is a binary file of compressed pixel data. The image embedded in the script is written out as ASCII characters. So I expected the script to be much larger. I suppose different images will have different results. In other words, your mileage may vary.
Now I can share my JSL script with others, and when they run it in JMP, they will see my graph, complete with the image. And they won't see the error message in the log that says the image file couldn't be found.
I hope you enjoy this little trick and, as always, please let me know what you think.