Ver Mensaje Individual
  #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