Foros del Web » Programación para mayores de 30 ;) » Programación General » Visual Basic clásico »

Animación gif en una aplicación

Estas en el tema de Animación gif en una aplicación en el foro de Visual Basic clásico en Foros del Web. Como puedo insertar una imagen gif en visual basic 6.0...
  #1 (permalink)  
Antiguo 13/09/2009, 12:53
 
Fecha de Ingreso: septiembre-2009
Mensajes: 1
Antigüedad: 14 años, 8 meses
Puntos: 0
Animación gif en una aplicación

Como puedo insertar una imagen gif en visual basic 6.0
  #2 (permalink)  
Antiguo 13/09/2009, 13:59
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: puedo meter una animacion flash (swf) en un formulario de visual basic 6.0

Para WACF

He encontrado esto:

----------
Se puede cargar el componente Microsoft Internet Controls. Luego ponerlo en pantalla e introducir este codigo en la forma

WebBrowser1.Navigate "C:\Internet\anim.gif"
-----------

Parece ser el unico modo sin usar una DLL externa.
Por lo visto hay una llamada Gif89.dll o algo asi y un ocx llamado marchoso, pero no los he buscado.

El problema es que no se ajusta al tamaño del gif. Debes cargar un gif del mismo tamaño que la ventana WebBrowser1 o apareceran barras de desplazamiento.

El caso es que si tu gif es un adorno y es pequeño te puede hacer el apaño.

Saludos
  #3 (permalink)  
Antiguo 15/09/2009, 12:53
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
Respuesta: Animación gif en una aplicación

Bienvenido al foro.

Mensajes transladados a un nuevo tema desde:
http://www.forosdelweb.com/f69/puedo...-6-0-a-184878/

Saludos.
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #4 (permalink)  
Antiguo 16/09/2009, 16:40
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: Animación gif en una aplicación

He encontrado otro método para hacerlo sin WebBrowser ni librerias externas, pero el resultado no es muy profesional.
Se extraen todos los fotogramas del gif, se crean tantos controles image como hagan falta y se cargan los fotogramas.
Con un Timer los vá mostrando/ocultando para simular la animación.
Problemas:
1 - Un parpadeo cuando acaba una secuencia y vuelve a empezar.
2 - Los gifs con transparencias o imágenes de diferentes tamaños no se reproducen bien.

Las pruebas que he hecho demuestran que, dependiendo del gif cargado, la visualización puede ser desde muy mala hasta perfecta, pasando por todas las demás calificaciones.

De momento os dejo esta versión que al menos funciona. La version original me daba error en alguna línea y haciendo lo mismo en 4 líneas no lo dá. Aún no lo he llegado a entender. ¡Ah! y le faltaba un End If a la sub del timer

He incluido los comentarios, si no del creador al menos de quien la publicó, en inglés y con traducción google para que mas o menos os entereis.

Hay que crear un formulario con 2 cosas:
Un control Image (Image1) CON EL VALOR INDEX = 0
osea una matriz de controles Image con el nombre Image1
Un Timer (Timer1)

Y como código ponemos esto:
NOTA: Del código solo hay que cambiar el camino y nombre del gif que quieres cargar.
NOTA2: No se me permite un mensaje tan largo. La Sub del Timer1 la pondré en otro mensaje a continuación.

Código :
Ver original
  1. Option Explicit
  2.  
  3. Dim NumberOfTimesToRepeatSequence As Long
  4. Dim RepeatedCount As Long
  5. Dim MaxCnt As Integer
  6. Dim ImgCnt As Integer
  7.  
  8. Private Sub Form_Load()
  9. On Error GoTo Form_LoadError
  10.  
  11. Image1(0).Left = 0
  12. Image1(0).Top = 0
  13.  
  14. 'place the path to the gif you want to animate here
  15. 'lugar de la ruta de acceso al GIF que desea animar aquí
  16. Call DecodeGif("C:\FicheroGifAnimado.gif")
  17. 'PONER AQUI EL FICHERO GIF
  18.  
  19. Exit Sub
  20.  
  21. Form_LoadError:
  22. MsgBox Err.Description
  23. End Sub
  24.  
  25. Private Sub DecodeGif(PathToGifFile As String)
  26. On Error GoTo DecodeGifError
  27.  
  28. 'declare procedural variables
  29. 'Declarar variables de procedimiento
  30. Dim FNumb As Integer
  31. Dim GifBuffer As String
  32. Dim GifHeader As String
  33. Dim SectionStart As Long
  34. Dim SectionEnd As Long
  35. Dim SectionMarker As String
  36. Dim ImageCount As Integer
  37. Dim I As Integer
  38. Dim NewPicBuff As String
  39. Dim ImageHeader As String
  40. Dim DisplayTime As Long
  41. Dim LftOffSet As Long
  42. Dim TopOffSet As Long
  43.  
  44. 'make sure we have something to work with
  45. 'asegurarnos de que tenemos algo con que trabajar
  46. If Dir(PathToGifFile) = vbNullString Then
  47.   MsgBox "Dónde está el GIF!?"
  48.   Exit Sub
  49. End If
  50.  
  51. 'disable timer
  52. 'temporizador desactivar
  53. Timer1.Enabled = False
  54.  
  55. 'if you were to change this demo so other gifs could be displayed in this array then you would need to unload all but the origional
  56. 'Si tuviera que cambiar esta demostración para que los gifs otras podrían ser mostradas en esta matriz, entonces usted tendría que descargar todos, pero el original
  57. For I = 1 To Image1.Count - 1
  58.   Unload Image1(I)
  59. Next I
  60.  
  61. 'set value(s)
  62. 'valor de referencia (s)
  63. SectionMarker = Chr(0) & "!ù"
  64. SectionStart = 1
  65.  
  66. 'open our gif, read it in, close it out
  67. 'abrir nuestro gif, leído en, cerca de fuera
  68. FNumb = FreeFile
  69. Open PathToGifFile For Binary As #FNumb
  70. GifBuffer = Input(FileLen(PathToGifFile), #FNumb)
  71. Close #FNumb
  72.  
  73. 'get where this (the header info) ends
  74. 'llegar a donde esta (la información de encabezado) termina
  75. SectionEnd = InStr(SectionStart, GifBuffer, SectionMarker) + Len(SectionMarker) - 2
  76.  
  77. 'retrieve the header
  78. 'recuperar la cabecera
  79. GifHeader = Left(GifBuffer, SectionEnd)
  80.  
  81. 'set where the next section starts at
  82. 'establecida en la siguiente sección se inicia en
  83. SectionStart = SectionEnd + 2
  84.  
  85. 'check the length of the header for extended information
  86. 'control de la longitud de la cabecera de información ampliada
  87. If Len(GifHeader) > 127 Then
  88.   NumberOfTimesToRepeatSequence = Asc(Mid(GifHeader, 127, 1))
  89.   NumberOfTimesToRepeatSequence = NumberOfTimesToRepeatSequence * 256
  90.   NumberOfTimesToRepeatSequence = NumberOfTimesToRepeatSequence + Asc(Mid(GifHeader, 126, 1))
  91. Else
  92.   NumberOfTimesToRepeatSequence = 0 'bucle infinito
  93. End If
  94.  
  95. 'now run through file an decode each frame
  96. 'ahora se ejecutan a través de un archivo de decodificar cada fotograma
  97. Do While SectionEnd <> Len(SectionMarker)
  98.  
  99. 'increase the count of images we have by 1
  100. 'aumentar el recuento de las imágenes que tenemos antes del 1 de
  101. ImageCount = ImageCount + 1
  102.  
  103. 'find out where the next section ends
  104. 'saber dónde termina la sección siguiente
  105. SectionEnd = InStr(SectionStart, GifBuffer, SectionMarker) + Len(SectionMarker)
  106.  
  107. 'check to make sure we have some information to use
  108. 'Asegúrese de que tenemos algo de información para uso
  109. If SectionEnd > Len(SectionMarker) Then
  110.  
  111.   'create a single frame gif from this information
  112.   'crear un gif solo cuadro de esta información
  113.   NewPicBuff = GifHeader & Mid(GifBuffer, SectionStart - 1, SectionEnd - SectionStart)
  114.  
  115.   'now write it to file so we can use the load picture function on it
  116.   'Ahora escribe a un archivo para que podamos usar la función de imagen de carga en ella
  117.   FNumb = FreeFile
  118.   Open App.Path & "\temp.gif" For Binary As #FNumb
  119.   Put #FNumb, 1, NewPicBuff
  120.   Close #FNumb
  121.  
  122.   'now extract some information about the file we just saved
  123.   'ahora extraer alguna información sobre el archivo que acaba de guardar
  124.   ImageHeader = Left(Mid(GifBuffer, SectionStart - 1, SectionEnd - SectionStart), 16)
  125.  
  126.  
  127.   'now calcualte the time that the image we just saved is to be displayed
  128.   'Ahora calcualte el momento en que la imagen que acaba de guardar se mostrará
  129.   DisplayTime = Asc(Mid(ImageHeader, 5, 1))
  130.   DisplayTime = DisplayTime * 256
  131.   DisplayTime = DisplayTime + Asc(Mid(ImageHeader, 4, 1))
  132.   DisplayTime = DisplayTime * 10
  133.  
  134.   'check to see if we have more than one image
  135.   'verificación para ver si tenemos más de una imagen
  136.   If ImageCount > 1 Then
  137.  
  138.     'retrieve offsets
  139.     'Recuperar las compensaciones
  140.     LftOffSet = Asc(Mid(ImageHeader, 10, 1))
  141.     LftOffSet = LftOffSet * 256
  142.     LftOffSet = LftOffSet + Asc(Mid(ImageHeader, 9, 1))
  143.     TopOffSet = Asc(Mid(ImageHeader, 12, 1))
  144.     TopOffSet = TopOffSet * 256
  145.     TopOffSet = TopOffSet + Asc(Mid(ImageHeader, 11, 1))
  146.    
  147.     'load a new control and set its properties
  148.     'carga un nuevo control y establecer sus propiedades
  149.     Load Image1(ImageCount - 1)
  150.     Image1(ImageCount - 1).ZOrder 0
  151.     Image1(ImageCount - 1).Left = Image1(0).Left + (LftOffSet * 15)
  152.     Image1(ImageCount - 1).Top = Image1(0).Top + (TopOffSet * 15)
  153.    
  154.   End If
  155.  
  156.   'set the amount of time that this frame of the gif image is to be displayed for and load the image
  157.   'establecer la cantidad de tiempo que este marco de la imagen GIF es que se muestra a favor y cargar la imagen de
  158.   Image1(ImageCount - 1).Tag = DisplayTime
  159.   Image1(ImageCount - 1).Picture = LoadPicture(App.Path & "\temp.gif")
  160.  
  161.   'don't need it anymore so kill it
  162.   'No lo necesitamos más y lo eliminamos
  163.   Kill App.Path & "\temp.gif"
  164.  
  165.   SectionStart = SectionEnd
  166.  
  167. End If
  168.  
  169. Loop
  170.  
  171. If SectionStart < Len(GifBuffer) Then
  172.  
  173.   'create a single frame gif from this information
  174.   'crear un gif solo cuadro de esta información
  175.   NewPicBuff = GifHeader & Mid(GifBuffer, SectionStart - 1, Len(GifBuffer) - SectionStart)
  176.  
  177.   'now write it to file so we can use the load picture function on it
  178.   'Ahora escribe a un archivo para que podamos usar la función de imagen de carga en ella
  179.   FNumb = FreeFile
  180.   Open App.Path & "\temp.gif" For Binary As #FNumb
  181.   Put #FNumb, 1, NewPicBuff
  182.   Close #FNumb
  183.  
  184.   'now extract some information about the file we just saved
  185.   'ahora extraer alguna información sobre el archivo que acaba de guardar
  186.   ImageHeader = Left(Mid(GifBuffer, SectionStart - 1, Len(GifBuffer) - SectionStart), 16)
  187.  
  188.   'now calcualte the time that the image we just saved is to be displayed
  189.   'Ahora calcualte el momento en que la imagen que acaba de guardar se mostrará
  190.   DisplayTime = Asc(Mid(ImageHeader, 5, 1))
  191.   DisplayTime = DisplayTime * 256
  192.   DisplayTime = DisplayTime + Asc(Mid(ImageHeader, 4, 1))
  193.   DisplayTime = DisplayTime * 10
  194.  
  195.   'check to see if we have more than one image
  196.   'verificación para ver si tenemos más de una imagen
  197.   If ImageCount > 1 Then
  198.  
  199.     'retrieve offsets
  200.     'Recuperar las compensaciones
  201.     LftOffSet = Asc(Mid(ImageHeader, 10, 1))
  202.     LftOffSet = LftOffSet * 256
  203.     LftOffSet = LftOffSet + Asc(Mid(ImageHeader, 9, 1))
  204.     TopOffSet = Asc(Mid(ImageHeader, 12, 1))
  205.     TopOffSet = TopOffSet * 256
  206.     TopOffSet = TopOffSet + Asc(Mid(ImageHeader, 11, 1))
  207.    
  208.     'load a new control and set its properties
  209.     'carga un nuevo control y establecer sus propiedades
  210.     Load Image1(ImageCount - 1)
  211.     Image1(ImageCount - 1).ZOrder 0
  212.     Image1(ImageCount - 1).Left = Image1(0).Left + (LftOffSet * 15)
  213.     Image1(ImageCount - 1).Top = Image1(0).Top + (TopOffSet * 15)
  214.  
  215.   End If
  216.  
  217.   'set the amount of time that this frame of the gif image is to be displayed for and load the image
  218.   'establecer la cantidad de tiempo que este marco de la imagen GIF es que se muestra a favor y cargar la imagen de
  219.   Image1(ImageCount - 1).Tag = DisplayTime
  220.   Image1(ImageCount - 1).Picture = LoadPicture(App.Path & "\temp.gif")
  221.  
  222.   'don't need it anymore so kill it
  223.   'No lo necesitamos más y lo eliminamos
  224.   Kill App.Path & "\temp.gif"
  225.  
  226. End If
  227.  
  228. 'set our variables that we will use to keep track of which frame of the animation we are on
  229. 'conjunto nuestras variables que vamos a utilizar para hacer un seguimiento de qué fotograma de la animación que estamos en
  230. ImgCnt = 0
  231. MaxCnt = Image1.Count - 1
  232.  
  233. 'set up the timer
  234. 'configurar el reloj
  235. Timer1.Interval = CInt(Image1(0).Tag)
  236. Timer1.Enabled = True
  237.  
  238. Exit Sub
  239. DecodeGifError:
  240.  
  241. MsgBox Err.Description
  242.  
  243. End Sub
continuará...

Última edición por pkj; 14/10/2009 a las 13:34
  #5 (permalink)  
Antiguo 16/09/2009, 16:41
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: Animación gif en una aplicación

Ahí vá la sub que faltaba...


Código :
Ver original
  1. Private Sub Timer1_Timer()
  2.  
  3. On Error GoTo Timer1_TimerError
  4.  
  5. 'increment,show, and set the next timers interval
  6. 'incremento de, mostrar y ajustar el temporizador de intervalos siguiente
  7. ImgCnt = ImgCnt + 1
  8. Image1(ImgCnt).Visible = True
  9. Timer1.Interval = CInt(Image1(ImgCnt).Tag)
  10.  
  11. 'for gifs that have a moving animation each frame is offset from the first frame by some amount so you need to make sure that the old frame is not
  12. 'Gifs para que tengan una animación en movimiento cada cuadro se desplaza desde el primer fotograma de una cierta cantidad por lo que necesita para asegurarse de que el marco de edad no es
  13. 'shown because you would get one image overlaid on another (or in some cases next to each other).
  14. 'que se muestra porque se van a obtener una imagen superpuesta sobre otra (o en algunos casos junto a la otra).
  15. If ImgCnt = 0 Then
  16.  
  17.   'for images with offsets you need to do this
  18.   'para las imágenes con las compensaciones que tiene que hacer este
  19.   Image1(MaxCnt).Visible = False
  20.  
  21. Else
  22.  
  23.   'for images with offsets you need to do this
  24.   'para las imágenes con las compensaciones que tiene que hacer este
  25.   Image1(ImgCnt - 1).Visible = False
  26.  
  27.   'check to see if we have reached the end of the animation
  28.   'comprobar si hemos llegado al final de la animación
  29.   If ImgCnt = MaxCnt Then
  30.  
  31.     'reset the counter to before the first element since the first thing we do when we enter this sub is to increment the element counter
  32.     'restablecer el contador a antes del primer elemento ya que lo primero que hacemos cuando entramos en este subprograma es incrementar el contador de elemento
  33.     ImgCnt = -1
  34.    
  35.     'this can be removed for continious play but since it was decoded above...
  36.     'Esto se puede quitar para jugar, pero continuas desde que fue descifrado por encima de ...
  37.     If NumberOfTimesToRepeatSequence = 0 Then
  38.    
  39.       DoEvents
  40.  
  41.     Else
  42.  
  43.       'increment the number of times this animation has played and then check to see if we have reached the limit and if we have then disable the timer
  44.       'incrementar el número de veces que ha jugado esta animación y luego comprobar si hemos llegado al límite y si tenemos, entonces, desactivar el temporizador de
  45.       RepeatedCount = RepeatedCount + 1
  46.       If RepeatedCount > NumberOfTimesToRepeatSequence Then Timer1.Enabled = False
  47.    
  48.     End If
  49.  
  50.   End If
  51. End If
  52. Exit Sub
  53.  
  54. Timer1_TimerError:
  55. MsgBox Err.Description
  56.  
  57. End Sub

Saludos by PKJ

Última edición por pkj; 14/10/2009 a las 13:55
  #6 (permalink)  
Antiguo 20/09/2009, 09:50
Avatar de seba123neo  
Fecha de Ingreso: febrero-2007
Ubicación: Esperanza, Santa Fe
Mensajes: 1.046
Antigüedad: 17 años, 2 meses
Puntos: 19
Respuesta: Animación gif en una aplicación

mas o menos como este:

Reproducir un Gif animado sin utilizar un Ocx

saludos.
__________________
" Todos Somos Ignorantes; lo que pasa es que no todos ignoramos las mismas cosas " - Albert Einstein
  #7 (permalink)  
Antiguo 15/11/2009, 04:23
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: Animación gif en una aplicación

Voy a intentar explicar yo mismo el funcionamiento del código que mostré anteriormente, al menos lo que crea necesario, para quien no se aclare.

Como mi inglés es muy básico no puedo limitarme a traducirlo bién.

Para calentar comenzaré por el timer que es facilito. Para la sub más gorda necesitaré tiempo.

Código :
Ver original
  1. Private Sub Timer1_Timer()
  2.  
  3. On Error GoTo Timer1_TimerError
  4.  
  5. ' imgcnt contiene el numero de index del control image que vamos a mostrar.
  6. ' cada vez que entramos en este timer se incrementa el contador
  7. ImgCnt = ImgCnt + 1
  8. 'y así mostramos una imagen diferente a la actual
  9. Image1(ImgCnt).Visible = True
  10. ' y fijamos el tiempo que se tiene que esperar antes de volver a entrar a este timer para mostrar otra imagen.
  11. Timer1.Interval = CInt(Image1(ImgCnt).Tag)
  12.  
  13. ' si es la primera imagen del gif
  14. If ImgCnt = 0 Then
  15.  
  16. ' ocultamos la ultima imagen de la matriz
  17.   Image1(MaxCnt).Visible = False
  18.  
  19. ' ahora se me ocurre: si solo hay una imagen [image(0)] en el gif ¿que sucedera? se ocultará siempre, ¿no?
  20. ' asi de primeras creo que se generará una animación con los images (0) y (1), y dará error al intentar mostrar image(1) si no existe. Si existe y está vacio o no da error solo notaremos quizá un parpadeo.
  21.  
  22. Else
  23.  
  24.   ' si no es la primera ocultamos la anterior
  25.   Image1(ImgCnt - 1).Visible = False
  26.  
  27.   ' si hemos llegado a la última imagen del gif
  28.   If ImgCnt = MaxCnt Then
  29.  
  30.     'restablecer el contador a antes del primer elemento ya que lo primero que hacemos cuando entramos en este subprograma es incrementar el contador de elemento
  31.     ImgCnt = -1
  32.   ' Nota: si miramos la sub DecodeGif veremos que hay un fallo, ya que se inicializa la variable ImgCnt con valor 0 en lugar de con valor -1, lo que hace que la primera vez que entramos al timer no se muestra la imagen 0, sino la imagen 1, saltandonos un fotograma.
  33.    
  34.     ' si este valor es 0 significa que se repite la animación indefinidamente
  35.     If NumberOfTimesToRepeatSequence = 0 Then
  36.       ' en ese caso se deja un poco de tiempo de proceso para refrescar la imagen y tal
  37.       DoEvents
  38.  
  39.     Else
  40.  
  41.       ' si hay un límite de repeticiones se lleva la cuenta
  42.       RepeatedCount = RepeatedCount + 1
  43.       ' y si se supera se detiene el timer para finalizar la animación
  44.       If RepeatedCount > NumberOfTimesToRepeatSequence Then Timer1.Enabled = False
  45.    
  46.     End If
  47.  
  48.   End If
  49. End If
  50. Exit Sub
  51.  
  52. Timer1_TimerError:
  53. MsgBox Err.Description
  54.  
  55. End Sub

Saludos by PKJ
__________________
No hay preguntas tontas, solo gente estup..., ¡No!, ¿como era? No hay gente que pregunte a tontos... ¡Nooo!... ¡Vaya cabeza!

Última edición por pkj; 15/11/2009 a las 04:33
  #8 (permalink)  
Antiguo 15/11/2009, 06:12
Avatar de pkj
pkj
 
Fecha de Ingreso: julio-2006
Ubicación: Órbita sincrónica
Mensajes: 899
Antigüedad: 17 años, 9 meses
Puntos: 29
Respuesta: Animación gif en una aplicación

Nota: Esta explicación es en respuesta a una petición de un compañero del foro.
Como podéis imaginar hay muchas cosas que no he estudiado en profundidad y no podré explicar, como el formato interno de un fichero gif, pero intentaré dar una aproximación.

Código :
Ver original
  1. Option Explicit
  2. Dim NumberOfTimesToRepeatSequence As Long
  3. Dim RepeatedCount As Long
  4. Dim MaxCnt As Integer
  5. Dim ImgCnt As Integer
  6. Private Sub Form_Load()
  7.   On Error GoTo Form_LoadError
  8.   Image1(0).Left = 0
  9.   Image1(0).Top = 0
  10.   'lugar de la ruta de acceso al GIF que desea animar aquí
  11.   Call DecodeGif("C:\FicheroGifAnimado.gif")
  12.   'PONER AQUI EL FICHERO GIF
  13.   Exit Sub
  14. Form_LoadError:
  15.   MsgBox Err.Description
  16. End Sub
  17.  
  18. Public Sub DecodeGif(PathToGifFile As String)
  19.  
  20.   ' si hay errores saltamos a la etiqueta DecodeGifError
  21.   On Error GoTo DecodeGifError
  22.  
  23.   'Declaramos las variables
  24.   Dim FNumb As Integer
  25.   Dim GifBuffer As String
  26.   Dim GifHeader As String
  27.   Dim SectionStart As Long
  28.   Dim SectionEnd As Long
  29.   Dim SectionMarker As String
  30.   Dim ImageCount As Integer
  31.   Dim i As Integer
  32.   Dim NewPicBuff As String
  33.   Dim ImageHeader As String
  34.   Dim DisplayTime As Long
  35.   Dim LftOffSet As Long
  36.   Dim TopOffSet As Long
  37.  
  38.   ' comprobamos básicamente si existe el fichero contenido en la variable PathToGifFile
  39.   If Dir(PathToGifFile) = vbNullString Then
  40.     MsgBox "Dónde está el GIF!?"
  41.     ' si no lo encuentra salimos
  42.     Exit Sub
  43.   End If
  44.  
  45.   'detenemos el timer y cualquier animación que pueda estar en marcha
  46.   Timer1.Enabled = False
  47.  
  48.   ' eliminamos las imágenes existentes por si ya hemos mostrado antes otra animación
  49.   For i = 1 To Image1.Count - 1
  50.     Unload Image1(i)
  51.   Next i
  52.   ' solo dejamos la imagen (0) como base para crear mas
  53.  
  54.   ' nos aseguramos de que el control image no va a cambiar de tamaño para adaptarse al tamaño de la imagen
  55.   Image1(0).Stretch = False
  56.   'set value(s)
  57.  
  58.   'valor de referencia (s)
  59.   SectionMarker = Chr(0) & "!ù"
  60.   ' Esto imagino que es algo técnico sobre el formato de un fichero gif.
  61.   ' Posiblemente son caracteres que encontraremos precediendo a cada imagen o algo así.
  62.  
  63.   ' Puntero que iremos usando para guardar la posicion de comienzo de cada seccion con la que trabajemos
  64.   SectionStart = 1
  65.  
  66.   ' el sistema nos dá un numero de fichero que no se está usando en otro open en este momento
  67.   FNumb = FreeFile  ' <--- Esto es mejor que esto ---> FNumb = 1
  68.  
  69.   'abrimos el fichero gif
  70.   Open PathToGifFile For Binary As #FNumb
  71.  
  72.   ' leemos todo el fichero y lo cargamos en un string llamado GifBuffer
  73.   GifBuffer = Input(FileLen(PathToGifFile), #FNumb)
  74.   ' y lo cerramos.
  75.   Close #FNumb
  76.  
  77.   ' Buscamos el final del encabezado del fichero gif usando los caracteres de sectionmarker
  78.   SectionEnd = InStr(SectionStart, GifBuffer, SectionMarker) + Len(SectionMarker) - 2
  79.  
  80.   'guardamos esa parte del comienzo del gif (encabezado-header) que contendrá datos sobre el gif...
  81.   GifHeader = Left(GifBuffer, SectionEnd)
  82.  
  83.   ' guardamos la posición de inicio de la primera imagen
  84.   SectionStart = SectionEnd + 2
  85.  
  86.   'según la longitud del encabezado calculamos si el gif es continuo o se repite un numero limitado de veces
  87.   If Len(GifHeader) > 127 Then
  88.     ' si es mayor que 127 extraemos la cantidad de ciclos que se va a repetir con la formula:
  89.     ' ((Numero ascii del caracter 127) * 256) + Numero ascii del caracter 126
  90.     NumberOfTimesToRepeatSequence = Asc(Mid(GifHeader, 127, 1))
  91.     NumberOfTimesToRepeatSequence = NumberOfTimesToRepeatSequence * 256
  92.     NumberOfTimesToRepeatSequence = NumberOfTimesToRepeatSequence + Asc(Mid(GifHeader, 126, 1))
  93.   Else
  94.     ' si el encabezado no es mayor de 127 es que el gif se repite continuamente
  95.     NumberOfTimesToRepeatSequence = 0 'bucle infinito
  96.   End If
  97.  
  98.  
  99.   ' aqui extraemos las imagenes
  100.  
  101.   ' esto no se como funciona exactamente pero hace un bucle mientras queden imagenes que extraer
  102.   Do While SectionEnd <> Len(SectionMarker)
  103.  
  104.   'llevamos un contador de imagenes extraidas para crear los controles image
  105.   ImageCount = ImageCount + 1
  106.  
  107.   'para saber dónde termina la sección
  108.   SectionEnd = InStr(SectionStart, GifBuffer, SectionMarker) + Len(SectionMarker)
  109.  
  110.   'Nos aseguramos de que hay alguna imagen en el gif
  111.   If SectionEnd > Len(SectionMarker) Then
  112.  
  113.     'capturamos el trozo marcado y lo precedemos con el encabezado del fichero Gif (imagino que para que mantenga el formato al guardarlo como imagen individual)
  114.     NewPicBuff = GifHeader & Mid(GifBuffer, SectionStart - 1, SectionEnd - SectionStart)
  115.    
  116.     'Ahora se escribe la imagen a un archivo para poder cargarla como nosotros queremos hacerlo
  117.     FNumb = FreeFile
  118.     Open App.Path & "\temp.gif" For Binary As #FNumb
  119.     Put #FNumb, 1, NewPicBuff
  120.     Close #FNumb
  121.    
  122.     'ahora guardamos los 16 primeros caracteres de cada imagen que nos dirán su duración, etc
  123.     ImageHeader = Left(Mid(GifBuffer, SectionStart - 1, SectionEnd - SectionStart), 16)
  124.    
  125.     'Ahora calculamos la duración de la imagen actual con una formula que usa el cuarto y el quinto de esos 16 caracteres guardados
  126.     DisplayTime = Asc(Mid(ImageHeader, 5, 1))
  127.     DisplayTime = DisplayTime * 256
  128.     DisplayTime = DisplayTime + Asc(Mid(ImageHeader, 4, 1))
  129.     DisplayTime = DisplayTime * 10
  130.    
  131.     ' si no es la primera imagen que guardamos...
  132.     If ImageCount > 1 Then
  133.  
  134.       ' calculamos la posición de la nueva imagen dentro del formulario usando para ello los caracteres 9,10,11 y 12 de los 16 de la cabecera de la imagen.
  135.       LftOffSet = Asc(Mid(ImageHeader, 10, 1))
  136.       LftOffSet = LftOffSet * 256
  137.       LftOffSet = LftOffSet + Asc(Mid(ImageHeader, 9, 1))
  138.  
  139.       TopOffSet = Asc(Mid(ImageHeader, 12, 1))
  140.       TopOffSet = TopOffSet * 256
  141.       TopOffSet = TopOffSet + Asc(Mid(ImageHeader, 11, 1))
  142.  
  143.       'carga un nuevo control image y establece sus propiedades
  144.       Load Image1(ImageCount - 1)
  145.  
  146.       Image1(ImageCount - 1).ZOrder 0  ' zorder nunca he entendido como funciona (ni usado)
  147.  
  148.       Image1(ImageCount - 1).Left = Image1(0).Left + (LftOffSet * 15)
  149.       Image1(ImageCount - 1).Top = Image1(0).Top + (TopOffSet * 15)
  150.      
  151.     End If
  152.    
  153.     ' Añado esto para evitar que se cuele un valor de interval no válido.
  154.     If DisplayTime < 0 Then DisplayTime = 0
  155.     If DisplayTime > 65535 Then DisplayTime = 65535
  156.     ' creo que ya no es necesario pero al principio me pasaba y por seguridad lo dejo.
  157.  
  158.    
  159.     'guardamos en la propiedad Tag el tiempo que debe mostrarse la imagen
  160.     Image1(ImageCount - 1).Tag = DisplayTime
  161.  
  162.     ' cargamos la imagen que habíamos guardado en un fichero
  163.     Image1(ImageCount - 1).Picture = LoadPicture(App.Path & "\temp.gif")
  164.    
  165.     'la imagen ya no hace falta y se elimina
  166.     Kill App.Path & "\temp.gif"
  167.    
  168.     ' nos colocamos en posicion para comenzar con la siguiente imagen a cargar
  169.     SectionStart = SectionEnd
  170.    
  171.   End If
  172.  
  173.   ' y asi tantas veces como imagenes haya
  174.   Loop
  175.  
  176.   ' si aun quedan datos en el fichero creamos una última imagen con eso
  177.   If SectionStart < Len(GifBuffer) Then
  178.  
  179.     NewPicBuff = GifHeader & Mid(GifBuffer, SectionStart - 1, Len(GifBuffer) - SectionStart)
  180.    
  181.     ' el proceso es igual que antes asi que quito comentarios.
  182.  
  183.     FNumb = FreeFile
  184.     Open App.Path & "\temp.gif" For Binary As #FNumb
  185.     Put #FNumb, 1, NewPicBuff
  186.     Close #FNumb
  187.    
  188.     ImageHeader = Left(Mid(GifBuffer, SectionStart - 1, Len(GifBuffer) - SectionStart), 16)
  189.    
  190.     DisplayTime = Asc(Mid(ImageHeader, 5, 1))
  191.     DisplayTime = DisplayTime * 256
  192.     DisplayTime = DisplayTime + Asc(Mid(ImageHeader, 4, 1))
  193.     DisplayTime = DisplayTime * 10
  194.  
  195.     If ImageCount > 1 Then
  196.    
  197.       LftOffSet = Asc(Mid(ImageHeader, 10, 1))
  198.       LftOffSet = LftOffSet * 256
  199.       LftOffSet = LftOffSet + Asc(Mid(ImageHeader, 9, 1))
  200.  
  201.       TopOffSet = Asc(Mid(ImageHeader, 12, 1))
  202.       TopOffSet = TopOffSet * 256
  203.       TopOffSet = TopOffSet + Asc(Mid(ImageHeader, 11, 1))
  204.      
  205.       Load Image1(ImageCount - 1)
  206.       Image1(ImageCount - 1).ZOrder 0
  207.       Image1(ImageCount - 1).Left = Image1(0).Left + (LftOffSet * 15)
  208.       Image1(ImageCount - 1).Top = Image1(0).Top + (TopOffSet * 15)
  209.    
  210.     End If
  211.    
  212.     If DisplayTime < 0 Then DisplayTime = 0
  213.     If DisplayTime > 65535 Then DisplayTime = 65535
  214.    
  215.     Image1(ImageCount - 1).Tag = DisplayTime
  216.     Image1(ImageCount - 1).Picture = LoadPicture(App.Path & "\temp.gif")
  217.     Kill App.Path & "\temp.gif"
  218.    
  219.   End If
  220.  
  221.   ' reiniciamos el contador de imagenes mostradas en el timer
  222.   ImgCnt = -1
  223.   ' y guardamos el numero de imagenes totales
  224.   MaxCnt = Image1.Count - 1
  225.    
  226.   ' muestro ya la primera imagen
  227.   Image1(0).Visible = True
  228.   ' esto creo que tambien sobra.
  229.   ' lo puse para que no se saltase la primera imagen pero creo que se arregló al poner ImgCnt = - 1
  230.  
  231.   'configurar el timer con la duración de la primera imagen
  232.   Timer1.Interval = CInt(Image1(0).Tag)
  233.   'y para finalizar activamos el timer para comenzar la animacion
  234.   Timer1.Enabled = True
  235.   Exit Sub
  236.  
  237. DecodeGifError:
  238.   ' esto lo añadi para saltarme un error
  239.   If Image1.Count > 0 And Err.Number = 50003 Then
  240.     Unload Image1(Image1.Count - 1)
  241.     ImageCount = ImageCount - 1
  242.   Else
  243.     MsgBox Err.Number & " - " & Err.Description
  244.   End If
  245.   Err.Clear
  246.  
  247.   ' Añado esto para extraer todos los
  248.   ' fotogramas que pueda aun con un error
  249.   Resume Next
  250. End Sub

Creo que eso es todo.

Saludos
__________________
No hay preguntas tontas, solo gente estup..., ¡No!, ¿como era? No hay gente que pregunte a tontos... ¡Nooo!... ¡Vaya cabeza!

Última edición por pkj; 16/11/2009 a las 05:33 Razón: Repasar comentarios
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 01:37.