Shell   07-12-2023, 12:44
#1
Buenas!.

Muchas veces vemos que los compañeros cuando diseñan un formulario y quieren usar un número de controles sobre este,
normalmente para crear algo gráfico pero sin dibujarlo. Imaginar que se quiere presentar una serie de imágenes sobre
el formulario principal.

Os voy a mostrar lo que consume de memoria cuando se hace con cinco x cinco controles pictureboxes sobre un formulario
y lo que consume cinco x cinco imágenes en un DrawingArea.

Cinco x Cinco. Pictureboxes distribuidos en un formulario.
Fijaros en el númerito de los MiB
El tamaño de la imagen es de: 40Kb

[Imagen: O3FD3db.png]


Cinco x Cinco usando imágenes escaladas sobre un DrawingArea.

[Imagen: pkv55pZ.png]

Casi el doble cuando se usa un conjunto de Pictureboxes.

Inconveniente, que el desarrollador no sepa usar la librería Paint.
Me ha costado recordar un poco como se hacía esto. Estoy algo oxidado en el tema gráfico.

Si aumentamos el número de imágenes se puede cuadriplicar el consumo en el caso de los pictureboxes.

Saludos
Última modificación: 07-12-2023, 12:48 por Shell.

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
guizans   10-12-2023, 18:19
#2
La diferencia de uso de memoria es brutal. Eso si, usar el método de los PictureBox tiene una ventaja y es si cuando se hace click en alguna imagen es mucho mas fácil de saber en donde se ha pulsado, mientras en el Drawing Area la cosa es un poco mas complicada. Todo dependerá del uso que se le vaya a dar.

Un saludo.
Shell   10-12-2023, 23:07
#3
(10-12-2023, 18:19)guizans escribió: Eso si, usar el método de los PictureBox tiene una ventaja y es si cuando se hace click en alguna imagen es mucho mas fácil de saber en donde se ha pulsado, mientras en el Drawing Area la cosa es un poco mas complicada.

Si, es más sencillo, pero se puede lograr con algo más de código.

[Imagen: lXkX0c4.gif]

No pude reducir más el ancho de la captura del gif.

Saludos

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
guizans   11-12-2023, 20:32
#4
Hombre Shell, que menos que compartir ese código Big Grin
Shell   12-12-2023, 00:57
#5
(11-12-2023, 20:32)guizans escribió: Hombre Shell, que menos que compartir ese código

No es problema, solo tienen que decirlo. Wink
Me lié con que debería incorporar la clase. No es algo sencillo.

Por ejemplo:

¿ Debe la clase incorporar un método de escalado o es mejor escalar en el FMain y luego pasarle la imagen ya escalada a la clase ?.
Mejor escalarla en otro lugar, ejemplo en el Fmain ( solo se haría una vez ).
Mientras que si el método se hace desde la clase , cada vez que se cree una instancia de la clase, tiene que estar escalando y escalando...un rollo.
Cuando dije que era complicado, es que lo es, comencé a darle vueltas, ¿ y si creo un método estático ?. Por ahora no.

Tampoco es un código optimizado.
Comencemos con el código que solo hace uso de Pictureboxes.
Un código menor, pero no tan ideal.

Código:
' Gambas class file

'En este ejemplo crearemos los pictureboxes y lo distribuiremos por el formulario

Const ALTOBANDERA As Integer = 64
Const ANCHOBANDERA As Integer = 64
Const NUMBANDERAS As Integer = 6
Const MARGEN As Integer = 5

Public Sub Form_Open()

  Dim ventanaancho As Integer
  Dim ventanalto As Integer
  Dim nummargenes As Integer
  Dim x As Integer
  Dim y As Integer
  Dim unabandera As PictureBox
  Dim indicesdebanderas As Integer

  nummargenes = NUMBANDERAS + 1
  ventanaancho = NUMBANDERAS * ANCHOBANDERA + nummargenes * MARGEN
  ventanalto = NUMBANDERAS * ALTOBANDERA + nummargenes * MARGEN

  With Me
    .Resizable = False
    .H = ventanalto
    .W = ventanaancho
  End With

  For y = 0 To NUMBANDERAS - 1
    For x = 0 To NUMBANDERAS - 1
      unabandera = New PictureBox(Me) As "Banderas"
      With unabandera
        'La imagen es estrechada para que quepa el ancho y alto del PictureBox. La proporción de la imagen no se mantiene
        .Mode = PictureBox.Fill
        .Picture = Picture.Load("AguilaBicefala.jpg") 'Bandera de Albania
        .Tag = indicesdebanderas
        .W = ANCHOBANDERA
        .H = ALTOBANDERA
        .y = MARGEN + y * ALTOBANDERA + y * MARGEN
        .x = MARGEN + x * ANCHOBANDERA + x * MARGEN
      End With
      Inc indicesdebanderas
    Next
  Next

End

Public Sub Banderas_MouseDown() 'Carece de Click

  With Message
    .Title = "Mostar Indice"
    .Info("Indice: " & Last.tag)
  End With

End

El código de la clase. Esta clase hereda de la clase Rect para aprovechar sus propiedades y sus métodos.
Añadimos ademas la imagen ya escalada en una propiedad.

Código:
Inherits Rect

'La clase se limita al dibujo y a las dimensiones de la misma
'Ademas se hace uso de la clase Rect que es lo "ideal" para temas de sprites.

Property imgbandera As Image Use $imgbandera
Property indice As Integer Use $indice

Public Sub _new(ialto As Integer, iancho As Integer, ix As Integer, iy As Integer, imb As Image)

  Me.H = ialto
  Me.W = iancho
  Me.x = ix
  Me.y = iy
  Me.imgbandera = imb
 
End

Public Sub DibujarBandera()

  Paint.DrawImage(Me.imgbandera, Me.x, Me.y, Me.W, Me.H)

End

Y ahora el formulario que hace uso de la misma. Parte del código del formulario se podía haber añadido a la clase.
El único problema que me encuentro es, ¿ debe la clase tenerlo ?.

Como la clase hereda de Rect, probablemente el método de detectar si se ha hecho clic sobre una imagen,
si deba contenerlo y no es difícil de hacer. Cuando digo que si la clase debe contener ese código, me refiero
que si es lo ideal en POO.

Código:
'En este ejemplo haremos uso de dibujar una serie de imagenes en un DrawingArea

Const ALTOBANDERA As Integer = 64
Const ANCHOBANDERA As Integer = 64
Const NUMBANDERAS As Integer = 6
Const MARGEN As Integer = 5

Private hImage2 As Image 'No tiene por que ser global
Private abanderas As New ClsBandera[]
Private banderascreadas As Boolean

Public Sub Form_Open()

  Me.Title = "Imágenes en DrawingArea"
  EscalarImagen()
  CrearBanderas()

End

Public Sub EscalarImagen()

  Dim hImage As Image
  Dim hbrush As PaintBrush

  hImage = Image.Load("AguilaBicefala.jpg")
  hImage2 = New Image(ANCHOBANDERA, ALTOBANDERA)

  'Partiendo de la imagen original, hImage se va a escalar la imagen y el resultado se guardará en hImage2
  Paint.Begin(hImage2)
  hbrush = Paint.Image(hImage)
  hbrush.Scale(ANCHOBANDERA / hImage.W, ALTOBANDERA / hImage.H)
  Paint.Brush = hbrush
  Paint.Rectangle(0, 0, ANCHOBANDERA, ALTOBANDERA)
  Paint.Fill
  Paint.End

End

Public Sub CrearBanderas()

  Dim i, j, x, y, cuenta As Integer
  Dim nummargenes As Integer
  Dim ventanaancho As Integer
  Dim ventanalto As Integer
  Dim unabandera As ClsBandera

  nummargenes = NUMBANDERAS + 1
  ventanaancho = NUMBANDERAS * ANCHOBANDERA + nummargenes * MARGEN
  ventanalto = NUMBANDERAS * ALTOBANDERA + nummargenes * MARGEN

  DrawingArea1.W = ventanaancho
  DrawingArea1.H = ventanalto

  For i = 0 To NUMBANDERAS - 1
    For j = 0 To NUMBANDERAS - 1
      y = MARGEN + i * ALTOBANDERA + i * MARGEN
      x = MARGEN + j * ANCHOBANDERA + j * MARGEN
      unabandera = New ClsBandera(ALTOBANDERA, ANCHOBANDERA, x, y, hImage2)
      cuenta += 1
      unabandera.indice = cuenta
      abanderas.Add(unabandera)
    Next
  Next
  'Solo cuando tegamos todos las imagenes, permitiremos que se dibuje en el DrawingArea
  banderascreadas = True

End

Public Sub DrawingArea1_Draw()

  Dim tbandera As ClsBandera

  '  Se han creado todas las imagenes ?.
  If banderascreadas Then
    'Adelante, dibujalas
    For Each tbandera In abanderas
      tbandera.DibujarBandera()
    Next
  Endif

End

Public Sub DrawingArea1_MouseDown()

  Dim tbandera As ClsBandera
 
  For Each tbandera In abanderas
    'Se ha hecho clic en alguna imagen ? ( Rectángulo)
    If tbandera.Contains(Mouse.x, Mouse.y) Then
      With Message
        .Title = "Mostar Indice"
        .Info("Indice: " & Str(tbandera.indice))
      End With
    Endif
  Next

End

Adjunto el ejemplo.
Ahora imaginar lo que sería crear eventos propios en el código de la clase, observadores, etc,etc.

Saludos
Archivos adjuntos
.gz
ComparacionCrearObjetosConDibujarlo-0.0.1.tar.gz (Tamaño: 52.24 KB Descargas: 1)
Última modificación: 12-12-2023, 01:00 por Shell.

"El conocimiento es la mejor inversión que se puede hacer" - Abraham Lincoln
guizans   12-12-2023, 22:02
#6
Muchas gracias, Shell

Tremenda currada.

Un saludo.
  
Usuarios navegando en este tema: 3 invitado(s)
Powered By MyBB, © 2002-2024 MyBB Group.
Made with by Curves UI.