我要求AI编写一个python asyncio来异步下载图像。
尝试了一下是可以下载图像的,不知道如何不保存就直接将图像二进制文件写入JMP表。
谢谢专家!
在 JMP 18 中,只有 JSL 可以将图像放入表中。
我之前曾警告过 AI 以这种方式调用 JSL
jmp.run_jsl = '''
dt = Data Table("ImageTable");
dt[{i + 1}, "Image"] = New Image(Open("{data_url}"));
'''
有谁能解答一下:白色文字是python,红色文字是jsl,python格式将红色jsl字符串(三引号分隔)中的{}替换为两个参数,base64data是png或者jpg文件的二进制数据,经过base64编码,这正是newimage所需要的。
唯一令我感到惊讶的部分是混合两种语言,尽管 lala 在下一篇文章中提出了几乎正确的解决方案。
我询问了AI并得到了分析:(grok3)
下面是代码段的详细英文解释,该代码段处理将下载的图像数据写入 JMP 数据表:
# 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("所有图像已写入JMP表!")
逐行解释
对于 i,(url,image_data)在枚举(结果)中:
results 是 asyncio.gather(*tasks) 返回的元组列表,其中每个元组包含 (url, image_data)。
url 是图像的源 URL(字符串)。
image_data 是图像的二进制数据(字节),如果下载失败则为 None。
enumerate(results) 为每个元组提供一个索引 i(从 0 开始),它将用于指定 JMP 数据表中的行。
此行迭代所有下载结果以准备将有效数据写入表中。
如果图像数据:
检查 image_data 是否不为 None,确保仅处理成功下载的图像。
如果下载失败(image_data 为 None),循环将跳到下一次迭代,避免后续步骤出现错误。
dt["URL"][i] = url
dt 是先前使用 jmp.DataTable("ImageTable") 创建的 JMP 数据表对象。
dt["URL"] 访问数据表中的“URL”列,其数据类型为jmp.DataType.Character(字符类型)。
dt["URL"][i] 将 url(图像的源地址)分配给“URL”列的第 i 行(从 0 开始的索引)。
这一步直接使用 JMP Python API 设置单元格值,记录图像的来源。
base64_data = base64.b64encode(image_data).decode('utf-8')
base64.b64编码(图像数据):
将二进制图像数据(image_data,一个字节对象)编码为 base64 格式,返回一个字节字符串。
Base64 是一种将二进制数据转换为 ASCII 字符串的方法,适用于基于文本的环境。
.解码(‘utf-8’):
将 base64 字节字符串解码为 UTF-8 编码字符串,生成纯文本 base64 表示形式(例如“iVBORw0KGgo...”)。
此步骤将二进制图像数据转换为 JSL 可以处理的字符串格式。
jsl_code = '''...'''
将 JSL(JMP 脚本语言)脚本定义为字符串,它将创建图像对象并将其分配给数据表。
脚本内容:
dt = Data Table("ImageTable");
dt[{} , "Image"] = New Image(CharToBlob("{}", "base64"));dt = 数据表(“ImageTable”);:
检索 JSL 中的“ImageTable”数据表,确保目标表正确。
dt[{},“图片”]:
{} 是一个占位符,将被 i + 1 替换,代表行号(JSL 使用基于 1 的索引,因此使用 i + 1)。
“图像”指定目标列名。
新图像(CharToBlob(“{}”,“base64”)):
CharToBlob(“{}”, “base64”):
将 base64 编码的字符串(由第二个 {} 中的 base64_data 替换)转换为二进制数据(Blob)。
“base64”向 JSL 表明输入字符串是 base64 格式。
新图像(...):
从二进制数据创建一个图像对象,与 JMP 的“表达式”列类型兼容。
.格式(i + 1,base64数据):
使用 Python 的字符串格式将 i + 1(行号)和 base64_data(base64 字符串)插入 JSL 脚本。
示例:如果 i = 0 且 base64_data = “iVBORw0KGgo...”,则生成的 jsl_code 变为:
dt = Data Table("ImageTable");
dt[1 , "Image"] = New Image(CharToBlob("iVBORw0KGgo...", "base64"));
jmp.run_jsl(jsl_code)
jmp.run_jsl 是一个执行 JSL 脚本的 JMP Python API 函数。
将生成的 jsl_code 传递给 JMP,执行以下操作:
将图像对象插入到“ImageTable”数据表第 i + 1 行的“Image”列中。
图像对象源自 base64_data,并将在 JMP 中显示为可查看的图像。
print("所有图片已写入JMP表格!")
循环完成后,打印一条中文消息:“所有图像已写入JMP表!”
这是一个简单的状态通知,用于确认操作的完成。
工作原理
数据流:
从结果中检索每个图像的 url 和 image_data。
将 url 直接写入“URL”列。
将 image_data 编码为 base64 字符串。
使用JSL将base64字符串转换为图像对象并写入“Image”列。
关键技术:
asyncio:处理异步图像下载。
base64:将二进制数据编码为字符串。
JSL:使用 CharToBlob 和 New Image 在 JMP 中处理图像。
JMP Python API:通过 jmp.run_jsl 连接 Python 和 JSL。
笔记:
“Image”列必须是jmp.DataType.Expression类型才能存储图像对象。
JSL 使用基于 1 的行索引,而 Python 的枚举基于 0,因此为 i + 1。
如果 image_data 为 None,则跳过处理以避免出现错误。
潜在的改进
错误处理:在 jmp.run_jsl(jsl_code) 周围添加一个 try-except 块来捕获 JSL 执行错误。
性能:对于大量图像,批量执行 JSL 而不是逐行调用。
调试:记录 base64_data 或 jsl_code 以进行故障排除。
此代码成功地将图像数据从内存写入 JMP 数据表,而无需保存到磁盘。
我多次尝试过python的asyncio异步下载速度比JSL的NewMultiHTTPRequest()快很多。