Este foro usa cookies
Este foro utiliza cookies para almacenar su información de inicio de sesión si está registrado y su última visita si no lo está. Las cookies son pequeños documentos de texto almacenados en su computadora; las cookies establecidas por este foro solo se pueden usar en este sitio web y no representan ningún riesgo de seguridad. Las cookies en este foro también rastrean los temas específicos que ha leído y la última vez que los leyó. Si Ud. continúa navegando, entenderemos que acepta todas las cookies.

Se almacenará una cookie en su navegador, independientemente de la elección, para evitar que se le vuelva a hacer esta pregunta. Podrá cambiar la configuración de sus cookies en cualquier momento utilizando el enlace en el pie de página.

El foro antiguo se encuentra accesible desde https://foro.gambas-es.org en modo de solo lectura.

Calificación:
  • 0 voto(s) - 0 Media
  • 1
  • 2
  • 3
  • 4
  • 5

Cual es la forma mas rapida y eficiente de cargar imagenes en un control.
#1

Hola amigos.
Estoy agregando la visualización de fotos en un panel en el que agrego por código una serie de picturebox donde les cargo la imagen de la foto pero es lento.
Estoy usando el siguiente código para lograr la carga de imágenes 128 o 256 pixeles de lado:
GAMBAS
  1. Public Function CanvasPic(sFile As String, iSize As Integer) As Picture
  2.   Dim pic As Picture
  3.   Dim img As Image
  4.   Dim sc As Float
  5.   Dim H, W As Integer
  6.   If Exist(sFile) Then
  7.     img = Image.Load(sFile)
  8.     If img.W >= img.H Then
  9.       sc = img.H / img.W
  10.       W = iSize
  11.       H = iSize * sc
  12.     Else
  13.       sc = img.W / img.H
  14.       W = iSize * sc
  15.       H = iSize
  16.     Endif
  17.     pic = img.Stretch(W, H).Picture
  18.   Return pic



Pero al ser tan lento no lo puedo implementar para representar muchas imágenes.
Alguien podría sugerir alternativas mas eficientes.
Muchas gracias de antemano.

1 Saludo.
    ¡Gracias!
#2

¿Cuanto "pesan" las imágenes antes de redimensionarlas?

He probado tu rutina y funciona de manera inmediata cargando imágenes .jpg con un peso de 500 K antes de redimensión.

GAMBAS
  1. Public Sub Button1_Click()
  2.  
  3.   Dim pic As Picture
  4.   Dim img As Image
  5.   Dim sc As Float
  6.   Dim H, W As Integer
  7.   Dim sFile As String
  8.   Dim iSize As Integer = 256
  9.   sFile = "/home/Comun/Fondos/187641361_4511982512149288_4569997526716770034_n.jpg"
  10.   If Exist(sFile) Then
  11.     Print Now
  12.     img = Image.Load(sFile)
  13.     Print Now
  14.     Print "-------------------------------"
  15.     If img.W >= img.H Then
  16.       sc = img.H / img.W
  17.       W = iSize
  18.       H = iSize * sc
  19.     Else
  20.       sc = img.W / img.H
  21.       W = iSize * sc
  22.       H = iSize
  23.     Endif
  24.     Print Now
  25.     pic = img.Stretch(W, H).Picture
  26.     Print Now
  27.     Print "== == == == == == == == == == == == == == == == == =="
  28.     PictureBox1.Picture = pic
  29.  



Y el resultado ha sido así:

17/11/2022 10:24:15
17/11/2022 10:24:15
-------------------------------
17/11/2022 10:24:15
17/11/2022 10:24:15
== == == == == == ==

Es decir, el tiempo empleado es del orden de los milisegundos. Habría que cambiar Now por otra función más apropiada paa medir tiempos tan cortos.
Es evidente que el cuello de botella solo puede estar en el Load o en el Stretch, el resto son solo cálculos aritméticos.
No sé cuantas imágenes tienes que cargar por segundo, en caso de que sea un carrusel, o realmente si el problema es solo de carga de una en una.

Si te puedo ayudar en algo mas, encantado, Pídeme las pruebas que necesites.

Un saludo.
    ¡Gracias!
#3

Sin entrar al fondo del asunto, una puntualización: Hay veces que no hay maneras más rápidas de hacer algo y uno debe renunciar a la inmediatez. En el gbAmp me encontré con esta situación en el cálculo de la duración de los ficheros de sonido, que no era posible hacerla de manera inmediata, por tanto lo derivé a "proceso de fondo" y se va haciendo mientras el programa continúa. Es lo que hacen también nautilus y similares, con un directorio con tropecientas fotos, si cambias de vista de lista detalle a iconos, verás que la miniatura se va rellenando poco a poco. Puede ser una manera de enfocar el problema.

Saludos

No podemos regresar
    ¡Gracias!
#4

He cambiado Now por CFloat(Now) y este es el resultado:
2492005,40379675
2492005,40379747
---------------------------
2492005,40379747
2492005,40379751
== == == == == ==
2492005,40379751  <-- Este lo he añadido después de PictureBox1.Picture = pic (para ver el tiempo de dibujado).

Como ves la diferencia de tiempos es ridícula.

Espero te sea útil.

Saludos.
    ¡Gracias!
#5

(17-11-2022, 11:32)gartumar2 escribió:   ...
...
Habría que cambiar Now por otra función más apropiada paa medir tiempos tan cortos.
...
...

¿Has probado "Activar Perfilado" en el menú "Depuración"? Ahí tienes eso y mucho más. Sólo ejecuta tu programa y cierralo después.
(Por cierto había ciertos problemas con QT si se hacía esto y el IDE debía abrirse con GTK (botón derecho en el menú del sistema)... o al revés, no recuerdo)

Saludos

No podemos regresar
    ¡Gracias!
#6

Nueva prueba. He cargado una imagen gorda, gorda, 36,4 MB antes de redimension. Estos han sido los resultados.

2492005,41794984
2492005,41795524
-------------------
2492005,41795524
2492005,41795588
== == == == == == ==
2492005,41795595

Se llega a apreciar el retardo en la carga, pero menos de un segundo.

Saludos.

(17-11-2022, 11:46)Shordi escribió:  ¿Has probado "Activar Perfilado" en el menú "Depuración"?

Acabo de aterrizar en Gambas y aún me estoy enterando poco a poco de lo que puedo (y no puedo) hacer. Gracias por la info. Voy a probar.

Saludos.

PD. Efectivamente la activación del perfilado me deja a Gambas frito, se queda bloqueado en Loading profiling file...... hasta que explota. Con Gtk funciona bien.
[-] Los siguientes 1 usuarios dice gracias a gartumar2 por este post:
  • tincho
    ¡Gracias!
#7

Prueba a ejecutarlo con QT5. Yo lo que hago es abrirlo con un shellscript que ubico en ~/.local/bin con este contenido

Bash
  1. #!/bin/sh
  2. #Si no existe el archivo de seguridad del día, lo creamos
  3. copia_diaria="/home/jorge/Datos/Gambas_seguridad/`date +%Y-%m-%d`.tar.gz"
  4. if [ ! -f $copia_diaria ]
  5. then
  6.     #Creamos el comprimido de copia de seguridad
  7.     tar -czvf $copia_diaria /home/jorge/gambas >/home/jorge/.local/bin/gambas_copias.log
  8. fi
  9. env GB_GUI=gb.qt5 gambas3



La última línea es la que abre gambas con qt5. Las otras me hacen una copia de seguridad al día de mi carpeta de proyectos. (Cierto que es algo que almacena un montón de copias redundantes y cada x tiempo tienes que limpiar... pero tener la copia de ayer, y anteayer y anteanteayer, es algo que me ha salvado el culo muchas veces).

Saludos

No podemos regresar
[-] Los siguientes 2 usuarios dicen gracias a Shordi por este post:
  • gartumar2, tincho
    ¡Gracias!
#8

(17-11-2022, 11:46)Shordi escribió:  (Por cierto había ciertos problemas con QT si se hacía esto y el IDE debía abrirse con GTK (botón derecho en el menú del sistema)... o al revés, no recuerdo)

Por si te satisface la curiosidad: las primeras ejecuciones con Perfilado activado en Qt4 y Qt5 han colgado Gambas, Luego con Gtk ha funcionado. Y a partir de ahí ya funciona con Qt4 y Qt5.
    ¡Gracias!
#9

(17-11-2022, 11:41)Shordi escribió:  Sin entrar al fondo del asunto, una puntualización: Hay veces que no hay maneras más rápidas de hacer algo y uno debe renunciar a la inmediatez. En el gbAmp me encontré con esta situación en el cálculo de la duración de los ficheros de sonido, que no era posible hacerla de manera inmediata, por tanto lo derivé a "proceso de fondo" y se va haciendo mientras el programa continúa. Es lo que hacen también nautilus y similares, con un directorio con tropecientas fotos, si cambias de vista de lista detalle a iconos, verás que la miniatura se va rellenando poco a poco. Puede ser una manera de enfocar el problema.

Saludos

Coincido con este aproach del problema. Ademas, podrías guardar las miniaturas como suelen hacer estos navegadores de archivos, con ello no tendrías que stretch-arlas  función que debe insumir algún tiempo.

"Es mejor saber todo de muy poco que muy poco de todo" - anonimo
    ¡Gracias!
#10

Estoy explorando el uso, a través de Extern, de la librería MagickWand para ello me sirvo de un ejemplo alojado en la wiki del foro gambas-it.org.
https://www.gambas-it.org/wiki/index.php...mageMagick
Bien la pegunta es:
¿Como convertir la variable tipo Pointer "magickwand", que ya contiene un la imagen redimensionada, en una imagen en memoria que pueda usar gambas?
Ya que para el uso que deseo darle no es necesario que la imagen redimensionada sea guardada en el sistema de archivos.
Encontré que hay una Struct de la siguiente forma:
C
  1. size_t     id
  2. char     name [MagickPathExtent]
  3. Image *     images
  4. ImageInfo *     image_info
  5. ExceptionInfo *     exception
  6. MagickBooleanType     insert_before
  7. MagickBooleanType     image_pending
  8. MagickBooleanType     debug
  9. size_t     signature


https://www.imagemagick.org/api/MagickWa...kWand.html
Pero no se como asignar el puntero a dicha estructura.

¿La imagen esta en "Image *     images" ? en ese caso ¿Como la convierto en una Image de gambas?

Este es el código modificado para usarlo como función, que no funciona:

GAMBAS
  1. ' Gambas module file
  2. Library "libMagickWand-6.Q16:6.0.0"
  3.  
  4. Private Enum MagickFalse = 0, MagickTrue
  5. Private Enum UndefinedFilter = 0, PointFilter, BoxFilter, TriangleFilter, HermiteFilter,
  6.   HanningFilter, HammingFilter, BlackmanFilter, GaussianFilter, QuadraticFilter,
  7.   CubicFilter, CatromFilter, MitchellFilter, JincFilter, SincFilter, SincFastFilter,
  8.   KaiserFilter, WelshFilter, ParzenFilter, BohmanFilter, BartlettFilter, LagrangeFilter,
  9.   LanczosFilter, LanczosSharpFilter, Lanczos2Filter, Lanczos2SharpFilter, RobidouxFilter,
  10.   RobidouxSharpFilter, CosineFilter, SplineFilter, LanczosRadiusFilter, SentinelFilter
  11.  
  12.   id As Integer
  13.   char As String
  14.   images As Pointer
  15.   image_info As String
  16.   exception As String
  17.   insert_before As Boolean
  18.   image_pending As Boolean
  19.   bdebug As Boolean
  20.   signature As Integer
  21.  
  22. ' void MagickWandGenesis(void)
  23. ' Initializes the MagickWand environment.
  24. Private Extern MagickWandGenesis()
  25.  
  26. ' MagickWand *NewMagickWand(void)
  27. ' Returns a wand required for all other methods in the API.
  28. Private Extern NewMagickWand() As Pointer
  29.  
  30. ' MagickBooleanType MagickReadImage(MagickWand *wand,const char *filename)
  31. ' Reads an image or image sequence.
  32. Private Extern MagickReadImage(wand As Pointer, filename As String) As Boolean
  33.  
  34. ' MagickBooleanType MagickResizeImage(MagickWand *wand, const size_t columns,const size_t rows,const FilterType filter)
  35. ' Scales an image to the desired dimensions with a filter.
  36. Private Extern MagickResizeImage(wand As Pointer, columns As Long, rows As Long, filter As Integer, blur As Float) As Boolean
  37.  
  38. ' MagickBooleanType MagickWriteImages(MagickWand *wand, const char *filename,const MagickBooleanType adjoin)
  39. ' Writes an image or image sequence.
  40. Private Extern MagickWriteImages(wand As Pointer, filename As String, adjoin As Boolean) As Boolean
  41.  
  42. ' MagickWand *DestroyMagickWand(MagickWand *wand)
  43. ' Deallocates memory associated with an MagickWand.
  44. Private Extern DestroyMagickWand(wand As Pointer) As Pointer
  45.  
  46. ' void MagickWandTerminus(void)
  47. ' Terminates the MagickWand environment.
  48. Private Extern MagickWandTerminus()
  49.  
  50.  
  51.   Dim bo As Boolean
  52.   Dim magickwand As Pointer
  53.   Dim w As New Swand
  54.   Dim fileimmagine, nuovofile As String
  55.   Dim img As Image
  56.  
  57.   MagickWandGenesis()
  58.  
  59.   magickwand = NewMagickWand()
  60.  
  61.   bo = MagickReadImage(magickwand, jpg)
  62.   If bo = MagickFalse Then
  63.     Error.Raise("Impossibile caricare il file immagine !")
  64.     Chiude(magickwand)
  65.  
  66.   ' Ridimensiona l'immagine:
  67.   MagickResizeImage(magickwand, 106, 80, LanczosFilter, 1.0)
  68.  
  69.   bo = MagickWriteImages(magickwand, nuovofile, MagickTrue)
  70.   If bo = MagickFalse Then
  71.     Error.Raise("Impossibile creare il nuovo file dell'immagine ridimensionata !")
  72.     Chiude(magickwand)
  73.   Else
  74.     w = magickwand
  75.     img = w.images
  76.  
  77.   Chiude(magickwand)
  78.  
  79.   If img Then
  80.     Return img
  81.   Else
  82.     Return Null
  83.  
  84.  
  85.  
  86.   ' Libera la memoria e chiude la libreria "ImageMagick":
  87.   DestroyMagickWand(mw)
  88.   Wait 0.01
  89.   MagickWandTerminus()
  90.  



(17-11-2022, 11:41)Shordi escribió:  con un directorio con tropecientas fotos, si cambias de vista de lista detalle a iconos, verás que la miniatura se va rellenando poco a poco.

Efectivamente, el esta sobre la mesa esa opción, de hecho tengo algo armado en otro programa que extrae las imágenes de un PDF para ello uso la clase Task de gambas que funciona súper bien para esto que decís.
De todas manera quisiera saber si esta forma que uso es mejorable.

(17-11-2022, 11:32)gartumar2 escribió:  ¿Cuanto "pesan" las imágenes antes de redimensionarlas?

Las imágenes son de unos 4Mb son fotos de teléfonos y cámaras.
Esto es para el programa Photo organizer que hace un tiempo estoy desarrollando y en el feedback de Shordi y TercoIDE me instaron a que se puedan ver las fotos y se pueda buscar en una base de datos, así que acá estoy tratando de lograr el desafío. Dodgy
El objetivo es mostrar unas miniaturas de las imágenes de un directorio d importación y también mostrar las imágenes del disco duro al buscar por fecha o por alguna otra restricción.

(17-11-2022, 12:04)gartumar2 escribió:  PD. Efectivamente la activación del perfilado me deja a Gambas frito, se queda bloqueado en Loading profiling file...... hasta que explota. Con Gtk funciona bien.

si, correcto, hay que usar QT para que funcione. Antes funcionaba con GTK pero algo cambio.

1 Saludo.
    ¡Gracias!


Posibles temas similares…
Tema / Autor Respuestas Vistas Último mensaje

Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)