- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
How to write python downloaded images directly to JMP tables without saving them?
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: How to write python downloaded images directly to JMP tables without saving them?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
Re: How to write python downloaded images directly to JMP tables without saving them?
Well, AI is still pretty smart.
Thanks Experts!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
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}"));
'''
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Get Direct Link
- Report Inappropriate Content
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().