cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
The Discovery Summit 2025 Call for Content is open! Submit an abstract today to present at our premier analytics conference.
Choose Language Hide Translation Bar
View Original Published Thread

How to write python downloaded images directly to JMP tables without saving them?

lala
Level VIII

I asked the AI to write a python asyncio to download images asynchronously.
Try is able to download the image, do not know how to write the image binary file directly to the JMP table without saving.

 

Thanks Experts!

 

8 REPLIES 8
lala
Level VIII


Re: How to write python downloaded images directly to JMP tables without saving them?

2025-02-28_22-49-14.png

jthi
Super User


Re: How to write python downloaded images directly to JMP tables without saving them?

If I remember correctly one method can be found from here Scripters Club Recording: Running Python Code within JSL 

-Jarmo


Re: How to write python downloaded images directly to JMP tables without saving them?

In JMP 18, only JSL can script putting images into the table.

lala
Level VIII


Re: How to write python downloaded images directly to JMP tables without saving them?

  • Well, AI is still pretty smart.

Thanks Experts!

2025-03-01_08-05-27.png

lala
Level VIII


Re: How to write python downloaded images directly to JMP tables without saving them?

  • I don't understand how it works

I had previously warned the AI to call JSL in this way

 

                jmp.run_jsl = '''
                dt = Data Table("ImageTable");
                dt[{i + 1}, "Image"] = New Image(Open("{data_url}"));
                '''

 

 

 

 

Craige_Hales
Super User


Re: How to write python downloaded images directly to JMP tables without saving them?

Anyone trying to puzzle it out: the white text is python. the red text is jsl. the python format replaces the {} in the red jsl string (delimited by triple quotation marks) with the two parameters. the base64data is the binary data of a png or jpg file, encoded as base64, which is what newimage needs.

The only part I'm surprised by is blending the two languages, although lala suggested almost the correct solution in the next post.

Craige
lala
Level VIII


Re: How to write python downloaded images directly to JMP tables without saving them?

I asked the AI and got the analysis:(grok3)

 

Below is a detailed English explanation of the code segment, which handles writing downloaded image data into a JMP data table:

# Write results to JMP data table
for i, (url, image_data) in enumerate(results):
    if image_data:
        dt["URL"][i] = url
        # Encode binary data to base64 and create a Blob object
        base64_data = base64.b64encode(image_data).decode('utf-8')
        # Create an image object using JSL's CharToBlob
        jsl_code = '''
        dt = Data Table("ImageTable");
        dt[{} , "Image"] = New Image(CharToBlob("{}", "base64"));
        '''.format(i + 1, base64_data)
        jmp.run_jsl(jsl_code)

print("All images have been written to JMP table!")
Line-by-Line Explanation
for i, (url, image_data) in enumerate(results):
results is a list of tuples returned by asyncio.gather(*tasks), where each tuple contains (url, image_data).
url is the source URL of the image (a string).
image_data is the binary data of the image (bytes), or None if the download failed.
enumerate(results) provides an index i (starting at 0) for each tuple, which will be used to specify the row in the JMP data table.
This line iterates over all download results to prepare writing valid data into the table.
if image_data:
Checks if image_data is not None, ensuring only successfully downloaded images are processed.
If the download failed (image_data is None), the loop skips to the next iteration, avoiding errors in subsequent steps.
dt["URL"][i] = url
dt is the JMP data table object created earlier with jmp.DataTable("ImageTable").
dt["URL"] accesses the "URL" column in the data table, which has the data type jmp.DataType.Character (character type).
dt["URL"][i] assigns the url (the image’s source address) to the i-th row (0-based indexing) of the "URL" column.
This step directly uses the JMP Python API to set the cell value, recording the image’s origin.
base64_data = base64.b64encode(image_data).decode('utf-8')
base64.b64encode(image_data):
Encodes the binary image data (image_data, a bytes object) into base64 format, returning a bytes string.
Base64 is a method to convert binary data into an ASCII string, suitable for text-based environments.
.decode('utf-8'):
Decodes the base64 bytes string into a UTF-8 encoded string, producing a plain text base64 representation (e.g., "iVBORw0KGgo...").
This step converts the binary image data into a string format that JSL can process.
jsl_code = '''...'''
Defines a JSL (JMP Scripting Language) script as a string, which will create an image object and assign it to the data table.
Script content:

dt = Data Table("ImageTable");
dt[{} , "Image"] = New Image(CharToBlob("{}", "base64"));

dt = Data Table("ImageTable");:
Retrieves the "ImageTable" data table in JSL, ensuring the correct table is targeted.
dt[{} , "Image"]:
{} is a placeholder that will be replaced by i + 1, representing the row number (JSL uses 1-based indexing, so i + 1 is used).
"Image" specifies the target column name.
New Image(CharToBlob("{}", "base64")):
CharToBlob("{}", "base64"):
Converts the base64-encoded string (replaced by base64_data in the second {}) into binary data (a Blob).
"base64" indicates to JSL that the input string is in base64 format.
New Image(...):
Creates an image object from the binary data, compatible with JMP’s "Expression" column type.
.format(i + 1, base64_data):
Uses Python’s string formatting to insert i + 1 (row number) and base64_data (base64 string) into the JSL script.
Example: If i = 0 and base64_data = "iVBORw0KGgo...", the resulting jsl_code becomes:

dt = Data Table("ImageTable");
dt[1 , "Image"] = New Image(CharToBlob("iVBORw0KGgo...", "base64"));


jmp.run_jsl(jsl_code)
jmp.run_jsl is a JMP Python API function that executes the JSL script.
Passes the generated jsl_code to JMP, performing the following:
Inserts an image object into the "Image" column at row i + 1 of the "ImageTable" data table.
The image object is derived from the base64_data and will be displayed as a viewable image in JMP.
print("所有图片已写入 JMP 表格!")
After the loop completes, prints a message in Chinese: "All images have been written to JMP table!"
This serves as a simple status notification to confirm the operation’s completion.
How It Works
Data Flow:
Retrieves url and image_data for each image from results.
Writes url directly to the "URL" column.
Encodes image_data into a base64 string.
Uses JSL to convert the base64 string into an image object and writes it to the "Image" column.
Key Technologies:
asyncio: Handles asynchronous image downloads.
base64: Encodes binary data into a string.
JSL: Uses CharToBlob and New Image to process images in JMP.
JMP Python API: Bridges Python and JSL via jmp.run_jsl.
Notes:
The "Image" column must be of type jmp.DataType.Expression to store image objects.
JSL uses 1-based row indexing, while Python’s enumerate is 0-based, hence i + 1.
Skips processing if image_data is None to avoid errors.
Potential Improvements
Error Handling: Add a try-except block around jmp.run_jsl(jsl_code) to catch JSL execution errors.
Performance: For large numbers of images, batch JSL execution instead of row-by-row calls.
Debugging: Log base64_data or jsl_code for troubleshooting.
This code successfully writes image data from memory into a JMP data table without saving to disk.

lala
Level VIII


Re: How to write python downloaded images directly to JMP tables without saving them?

I have repeatedly tried python's asyncio asynchronous download speed much faster than JSL's New Multi HTTP Request().