Le pedí a la IA que escribiera un asyncio en Python para descargar imágenes de forma asincrónica.
Intenta descargar la imagen, no sabes cómo escribir el archivo binario de la imagen directamente en la tabla JMP sin guardar.
¡Gracias expertos!
En JMP 18, solo JSL puede crear scripts para colocar imágenes en la tabla.
Previamente había advertido a la IA que llamara a JSL de esta manera.
jmp.run_jsl = '''
dt = Data Table("ImageTable");
dt[{i + 1}, "Image"] = New Image(Open("{data_url}"));
'''
Cualquiera que intente resolverlo: el texto blanco es Python. El texto rojo es JSL. El formato Python reemplaza {} en la cadena jsl roja (delimitada por comillas triples) con los dos parámetros. Los datos base64 son los datos binarios de un archivo png o jpg, codificados como base64, que es lo que necesita newimage.
La única parte que me sorprende es la mezcla de los dos idiomas, aunque lala sugirió casi la solución correcta en la siguiente publicación.
Le pregunté a la IA y obtuve el análisis: (grok3)
A continuación se muestra una explicación detallada en inglés del segmento de código que maneja la escritura de datos de imágenes descargadas en una tabla de datos 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("¡Todas las imágenes se han escrito en la tabla JMP!")
Explicación línea por línea
para i, (url, image_data) en enumerate(results):
results es una lista de tuplas devueltas por asyncio.gather(*tasks), donde cada tupla contiene (url, image_data).
url es la URL de origen de la imagen (una cadena).
image_data son los datos binarios de la imagen (bytes), o None si falló la descarga.
enumerate(results) proporciona un índice i (que comienza en 0) para cada tupla, que se utilizará para especificar la fila en la tabla de datos JMP.
Esta línea itera sobre todos los resultados de descarga para preparar la escritura de datos válidos en la tabla.
si imagen_datos:
Comprueba si image_data no es None, lo que garantiza que solo se procesen las imágenes descargadas correctamente.
Si la descarga falla (image_data es None), el bucle salta a la siguiente iteración, evitando errores en los pasos posteriores.
dt["URL"][i] = url
dt es el objeto de tabla de datos JMP creado anteriormente con jmp.DataTable("ImageTable").
dt["URL"] accede a la columna "URL" en la tabla de datos, que tiene el tipo de datos jmp.DataType.Character (tipo de carácter).
dt["URL"][i] asigna la URL (la dirección de origen de la imagen) a la fila i-ésima (indexación basada en 0) de la columna "URL".
Este paso utiliza directamente la API de Python JMP para establecer el valor de la celda y registrar el origen de la imagen.
base64_data = base64.b64encode(datos_de_imagen).decode('utf-8')
base64.b64encode(datos_de_imagen):
Codifica los datos de la imagen binaria (image_data, un objeto de bytes) en formato base64 y devuelve una cadena de bytes.
Base64 es un método para convertir datos binarios en una cadena ASCII, adecuado para entornos basados en texto.
.decodificar('utf-8'):
Descodifica la cadena de bytes base64 en una cadena codificada en UTF-8, produciendo una representación base64 de texto simple (por ejemplo, "iVBORw0KGgo...").
Este paso convierte los datos de la imagen binaria en un formato de cadena que JSL puede procesar.
jsl_code = '''...'''
Define un script JSL (JMP Scripting Language) como una cadena, que creará un objeto de imagen y lo asignará a la tabla de datos.
Contenido del guión:
dt = Data Table("ImageTable");
dt[{} , "Image"] = New Image(CharToBlob("{}", "base64"));dt = Tabla de datos("ImageTable");:
Recupera la tabla de datos "ImageTable" en JSL, garantizando que se seleccione la tabla correcta.
dt[{} , "Imagen"]:
{} es un marcador de posición que será reemplazado por i + 1, que representa el número de fila (JSL usa indexación basada en 1, por lo que se usa i + 1).
"Imagen" especifica el nombre de la columna de destino.
Nueva imagen(CharToBlob("{}", "base64")):
CharToBlob("{}", "base64"):
Convierte la cadena codificada en base64 (reemplazada por base64_data en el segundo {}) en datos binarios (un Blob).
"base64" indica a JSL que la cadena de entrada está en formato base64.
Nueva imagen(...):
Crea un objeto de imagen a partir de datos binarios, compatible con el tipo de columna "Expresión" de JMP.
.format(i + 1, base64_data):
Utiliza el formato de cadena de Python para insertar i + 1 (número de fila) y base64_data (cadena base64) en el script JSL.
Ejemplo: Si i = 0 y base64_data = "iVBORw0KGgo...", el jsl_code resultante se convierte en:
dt = Data Table("ImageTable");
dt[1 , "Image"] = New Image(CharToBlob("iVBORw0KGgo...", "base64"));
jmp.run_jsl(código jsl)
jmp.run_jsl es una función de la API de Python de JMP que ejecuta el script JSL.
Pasa el jsl_code generado a JMP, realizando lo siguiente:
Inserta un objeto de imagen en la columna "Imagen" en la fila i + 1 de la tabla de datos "ImageTable".
El objeto de imagen se deriva de base64_data y se mostrará como una imagen visible en JMP.
print("所有图片已写入 JMP 表格!")
Una vez completado el bucle, imprime un mensaje en chino: "¡Todas las imágenes se han escrito en la tabla JMP!"
Esto sirve como una notificación de estado simple para confirmar la finalización de la operación.
Cómo funciona
Flujo de datos:
Recupera la URL y los datos de imagen de cada imagen de los resultados.
Escribe la URL directamente en la columna "URL".
Codifica image_data en una cadena base64.
Utiliza JSL para convertir la cadena base64 en un objeto de imagen y lo escribe en la columna "Imagen".
Tecnologías clave:
asyncio: maneja descargas de imágenes asincrónicas.
base64: codifica datos binarios en una cadena.
JSL: utiliza CharToBlob y New Image para procesar imágenes en JMP.
API de Python de JMP: une Python y JSL a través de jmp.run_jsl.
Notas:
La columna "Imagen" debe ser del tipo jmp.DataType.Expression para almacenar objetos de imagen.
JSL utiliza indexación de filas basada en 1, mientras que la enumeración de Python está basada en 0, por lo tanto i + 1.
Omite el procesamiento si image_data es None para evitar errores.
Posibles mejoras
Manejo de errores: agregue un bloque try-except alrededor de jmp.run_jsl(jsl_code) para detectar errores de ejecución de JSL.
Rendimiento: para grandes cantidades de imágenes, ejecución de JSL por lotes en lugar de llamadas fila por fila.
Depuración: Registre base64_data o jsl_code para solucionar problemas.
Este código escribe con éxito datos de imagen desde la memoria a una tabla de datos JMP sin guardarlos en el disco.
He probado repetidamente la velocidad de descarga asincrónica de asyncio de Python mucho más rápida que la nueva solicitud HTTP múltiple () de JSL.