我要求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}"));
'''
有誰能解答一下:白色文字是蟒蛇。紅色文字是 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()快很多。