PowerBuilder
Procesamiento de imágenes en memoria con PowerBuilder 2025 R2 y .NET

0 visualizaciones
Cómo editar, versionar, comparar y exportar imágenes sin convertir el disco en un área de trabajo temporal.
Un editor de imágenes parece una aplicación dominada por la interfaz: abrir, rotar, redimensionar, voltear y guardar. Sin embargo, su decisión arquitectónica más importante está debajo de la ventana: dónde vive cada versión mientras el usuario trabaja. PB Image Memory Studio mantiene el original, el resultado activo, las miniaturas y el historial en memoria. El disco participa al abrir la fuente y al exportar el resultado final; no se utiliza para encadenar archivos temporales.
La memoria es parte del diseño, no un detalle de implementación
Trabajar con Blob evita que cada operación dependa de crear, localizar, volver a abrir y eliminar un archivo intermedio. El flujo interactivo queda contenido en RAM y la aplicación controla explícitamente cuándo un resultado se convierte en un archivo permanente.
La pantalla conecta el resultado visible con sus datos reales: 100 × 100 píxeles, formato PNG, nueve versiones y 365.3 KB aproximados en el historial. “Ver original” y “Ver resultado” permiten comparar sin generar archivos auxiliares.
Por qué evitar archivos temporales
La memoria también reduce riesgos operativos: colisiones de nombres, permisos de escritura, antivirus inspeccionando cada temporal, rutas que cambian entre el IDE y el ejecutable, o resultados parciales visibles si una escritura se interrumpe. Esto no significa que RAM sea “gratis”. Cada versión aumenta el consumo y las imágenes decodificadas pueden ocupar mucho más que sus archivos comprimidos. Por eso el demo muestra el uso aproximado del historial y libera de forma determinista los recursos gráficos administrados y no administrados.
Arquitectura del demo
El recorrido principal puede resumirse así:
La DLL que hace posible el procesamiento
El demo utiliza una DLL propia llamada PBImageMemoryStudio.Puente.dll. Su fuente está en src\puente_imagen\MotorImagen.cs y el script compilar_puente.ps1 la genera directamente en la raíz del proyecto. No es una librería genérica descargada ni un componente COM: es un ensamblado .NET Framework creado específicamente para este laboratorio.
PowerBuilder localiza el ensamblado en la carpeta desde la que se ejecuta el demo:
1String ls_ruta23ls_ruta = GetCurrentDirectory() + "\PBImageMemoryStudio.Puente.dll"4If inv_puente.of_inicializar(ls_ruta) Then Return True
Después, nvo_puente_imagen crea DotNetAssembly, carga la DLL con LoadWithDotNetFramework, instancia un DotNetObject y lo vincula con la clase PBImageMemoryStudio.MotorImagen. Esa clase publica cuatro operaciones centrales:
• ObtenerMetadatos(byte[]): ancho, alto, formato y canal alfa.
• ProcesarImagen(byte[], ...): redimensionamiento, volteo, rotación y codificación.
• CrearMiniatura(byte[], ...): representación proporcional para el historial.
• ConvertirFormato(byte[], ...): codificación final antes de exportar.
El tratamiento correcto de memoria en C#
Una imagen no es solamente el arreglo comprimido. Al decodificarla, GDI+ reserva superficies y manejadores nativos. El motor utiliza bloques using para que cada Image, Bitmap, Graphics, MemoryStream y EncoderParameters se libere incluso si ocurre una excepción.
1public byte[] ProcesarImagen(byte[] datos, int ancho, int alto,2 double angulo, bool voltearHorizontal, bool voltearVertical,3 string formato, int calidad)4{5 using (Image origen = CargarImagen(datos))6 using (Bitmap redimensionada = Redimensionar(origen, ancho, alto))7 using (Bitmap volteada = Voltear(redimensionada, voltearHorizontal, voltearVertical))8 using (Bitmap rotada = Rotar(volteada, angulo))9 {10 return Codificar(rotada, formato, calidad);11 }12}
El valor devuelto vuelve a PowerBuilder como Blob. Los objetos gráficos usados durante el cálculo ya no quedan vivos; solo permanece la representación codificada necesaria para la versión activa y el historial.
Historial, Deshacer y Rehacer sin disco
str_estado_imagen guarda la imagen, su miniatura, dimensiones, formato, operación, rotación, volteos, fecha, duración y tamaño. nvo_historial_imagen agrega cada estado a un arreglo y mueve il_posicion para Deshacer y Rehacer. Si el usuario retrocede y crea una transformación nueva, el nuevo estado sustituye la rama futura.
El diagnóstico suma Len(imagen) y Len(miniatura) para todas las versiones vigentes. Es una medición útil del almacenamiento de Blobs, aunque no representa por sí sola el pico temporal de memoria de GDI+ durante una transformación.
Mostrar el tamaño real también importa
Procesar correctamente no basta si la interfaz estira siempre la imagen para llenar el lienzo. La ventana convierte las dimensiones mediante PixelsToUnits, muestra el resultado a escala 1:1 cuando cabe y lo centra. Si el resultado supera el área disponible, lo reduce proporcionalmente solo para visualizarlo. El Blob no se modifica durante este ajuste visual.
Esta diferencia explica por qué una salida de 100 × 100 píxeles debe verse pequeña al seleccionar “Ver resultado”, mientras “Ver original” recupera el área completa de comparación. La interfaz comunica la transformación en lugar de ocultarla detrás de un escalado automático.
La escritura al disco ocurre una sola vez
Al exportar, el controlador solicita a la DLL la codificación elegida y abre únicamente el destino final:
1lbl_exportacion = inv_puente.of_convertir_formato(2 ib_imagen_actual, as_formato, al_calidad)34ll_archivo = FileOpen(as_ruta, StreamMode!, Write!, LockWrite!, Replace!)5ll_escritos = FileWriteEx(ll_archivo, lbl_exportacion)6FileClose(ll_archivo)
PNG conserva transparencia; JPEG aplica un nivel de calidad entre 1 y 100; BMP y GIF utilizan sus codificadores correspondientes. Hasta ese momento, las operaciones intermedias permanecen en memoria.
Estructura de ejecución
1Demo_PB_Image_Memory_Studio\2├── demo_pb_image_memory_studio.pbt3├── demo_pb_image_memory_studio.pbl4├── PBImageMemoryStudio.Puente.dll5├── src\6│ ├── nvo_controlador_estudio_imagen.sru7│ ├── nvo_historial_imagen.sru8│ ├── nvo_puente_imagen.sru9│ └── puente_imagen\MotorImagen.cs10└── articulo_appeon\11 ├── articulo_procesamiento_imagenes_memoria_es.html12 ├── article_in_memory_image_processing_en.html13 └── imagen1.png
Conclusión
PB Image Memory Studio demuestra que PowerBuilder puede conservar la experiencia visual y la organización tradicional en NVO mientras delega una operación especializada a .NET. La parte decisiva no es únicamente rotar o redimensionar: es mantener un ciclo de vida claro para los datos.
La imagen entra una vez, evoluciona como Blob, conserva versiones navegables y sale cuando el usuario decide exportar. La DLL aporta GDI+ y codificación; PowerBuilder aporta coordinación, historial, diagnóstico y experiencia de usuario. La memoria une ambas capas y convierte una sucesión de archivos temporales en un flujo controlado, visible y reversible.