Autor
|
Tema: Animar Gif como fondo de escritorio, va muy lento. (Leído 4,988 veces)
|
**Aincrad**
|
Hola, tengo una duda, haber si alguien podria ayudarme.
Estoy intentando poner un gif de fondo de pantalla , para eso... se me ocurre obtener cada frame del gif y cada frame , lo pongo de fondo de escritorio. pero el problema es que va lageado.
Esto es lo que estoy haciando :Para manipular el Gif , uso la clase de elektro, yo hice la mia, pero consume mucha memoria. asi que F. Clase : https://foro.elhacker.net/net/libreria_de_snippets_para_vbnet_compartan_aqui_sus_snippets-t378770.0.html;msg2116514#msg2116514Y lo que estoy haciendo : ' StartEngine("C:\Users\S4Lsalsoft\Pictures\06bdf8ad69ff62062ae7dceb250d8866.gif") <DllImport("user32.dll", CharSet:=CharSet.Auto)> Private Shared Function SystemParametersInfo(ByVal uAction As Integer, ByVal uParam As Integer, ByVal lpvParam As String, ByVal fuWinIni As Integer) As Integer End Function Const SPI_SETDESKWALLPAPER As Integer = 20 Const SPIF_UPDATEINIFILE As Integer = &H1 Const SPIF_SENDWININICHANGE As Integer = &H2 Public Sub StartEngine(ByVal GifPath As String) Dim key As RegistryKey = Registry.CurrentUser.OpenSubKey("Control Panel\Desktop", True) key.SetValue("WallpaperStyle", 1.ToString()) key.SetValue("TileWallpaper", 0.ToString()) key.Dispose() Dim Asynctask As New Task(New Action(Sub() Dim gif As New GIF(GifPath) Do Until gif.EndOfFrames ' Iterate frames until the end of frame count. Dim CurrentFrame As Image = gif.NextFrame() CurrentFrame.Save("BackgroundFrames\displayImage" & gif.ActiveFrameIndex & ".bmp") CurrentFrame.Dispose() Dim tempPath As String = Path.Combine(Application.StartupPath, "BackgroundFrames\displayImage" & gif.ActiveFrameIndex & ".bmp") SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, tempPath, SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE) ' Thread.Sleep(60) ' Simulate a FPS thingy. Application.DoEvents() If (gif.EndOfFrames) Then ' Set active frame to 0 for infinite loop: gif.ActiveFrameIndex = 0 End If Loop End Sub), TaskCreationOptions.PreferFairness) Asynctask.Start() End Sub
Funciona pero va muy lento , alguna solucion? , gracias de antemano .
|
|
|
En línea
|
|
|
|
Serapis
|
El principal problema de la lentitud, recáe en que un gif, es una cantidad de frames comprimidos y con transparencia (habitualmente), luego meterlo en un bucle, exige cada vez tener que descomprimir cada frame y recalcular y luego además como has elegido el modo 'tile', lo que supone que cada frame se repetirá hasta completar el tamaño de la pantalla, con tantas filas y columnas como se precisen (o recortar la imagen si excediera el tamaño de la pantalla). Un típico visualizador de gif, lo que hace es en primer lugar extraer cada frame, esto es descomprimirlo y calcular la transparencia respecto del previo, de modo que se obtienen los frames descomprimidos simplemente como un 'picture' (un bitmap), serán luego esos bitmaps, los que iteren en el bucle... pero solo se descomprimen del fichero una sola vez. Ahí radica la principal desventaja de tu código. array de picture bitmaps() entero numFrames
numframes = funcion ExtraerFrames(gif gif) picture frame, framefull dimensionar bitmaps(0 a gif.NumFrames) por cada frame en gif.Frames frameFull = ResizeFrame(desktop.width, desktop.Height, frame, tile) bitmaps(x)= frameFull x+=1 siguiente
devolver gif.NumFrames fin funcion
Una vez tomados los frames, ya puedes en tu bucle rotar entre entre ellos pero ahora de un array de imágenes, que no necesitan ser descomprimidas cada vez (aunque ignoro si tu objeto gif, ya las tiene extraídas de una vez) y que ya cada uno tiene ahora el tamaño del escritorio (y no escalar con cada cambio de imagen). Por supuesto ahora teniendo cada imagen el tamaño del escritorio, debería signarse 'centrado' no 'tile' (que se retiene en la imagen)... Por último, deberías detectar si hay cambio de orientación o del tamaño del escritorio (el cambio de orientación es un cambio de tamaño, excepto cuando rota 180º), para readaptar (invocar de nuevo el código previo para reconstruir) los frames al nuevo tamaño del escritorio. Pero insisto en que no es buena idea hacer que el escritorio cambie constantemente su fondo. El escritorio es la ventana 0, todo el resto del IDE de windows cuelga de él, es la raíz. Cualquier sobrecarga en el uso o refresco del escritorio, supone un lastre para el resto. Piensa que otro agravio en la lentitud, es que el escritorio ha de recortar todos los elementos que contiene para pegar la imagen... Si al menos estuviera vacío... se evitaría el recorte, pero claro entonces no se distinguiría de un 'salvapantallas'... Como mínimo en tu bucle o bien pones un intervalo alto entre cambio de imágenes... o que se detenga cuando descubra que otros procesos (que no son el tuyo), consumen/demandan recursos del procesador...
|
|
|
En línea
|
|
|
|
**Aincrad**
|
El principal problema de la lentitud, recáe en que un gif, es una cantidad de frames comprimidos y con transparencia (habitualmente), luego meterlo en un bucle, exige cada vez tener que descomprimir cada frame y recalcular y luego además como has elegido el modo 'tile', lo que supone que cada frame se repetirá hasta completar el tamaño de la pantalla, con tantas filas y columnas como se precisen (o recortar la imagen si excediera el tamaño de la pantalla). Un típico visualizador de gif, lo que hace es en primer lugar extraer cada frame, esto es descomprimirlo y calcular la transparencia respecto del previo, de modo que se obtienen los frames descomprimidos simplemente como un 'picture' (un bitmap), serán luego esos bitmaps, los que iteren en el bucle... pero solo se descomprimen del fichero una sola vez. Ahí radica la principal desventaja de tu código. array de picture bitmaps() entero numFrames
numframes = funcion ExtraerFrames(gif gif) picture frame, framefull dimensionar bitmaps(0 a gif.NumFrames) por cada frame en gif.Frames frameFull = ResizeFrame(desktop.width, desktop.Height, frame, tile) bitmaps(x)= frameFull x+=1 siguiente
devolver gif.NumFrames fin funcion
Una vez tomados los frames, ya puedes en tu bucle rotar entre entre ellos pero ahora de un array de imágenes, que no necesitan ser descomprimidas cada vez (aunque ignoro si tu objeto gif, ya las tiene extraídas de una vez) y que ya cada uno tiene ahora el tamaño del escritorio (y no escalar con cada cambio de imagen). Por supuesto ahora teniendo cada imagen el tamaño del escritorio, debería signarse 'centrado' no 'tile' (que se retiene en la imagen)... Por último, deberías detectar si hay cambio de orientación o del tamaño del escritorio (el cambio de orientación es un cambio de tamaño, excepto cuando rota 180º), para readaptar (invocar de nuevo el código previo para reconstruir) los frames al nuevo tamaño del escritorio. Pero insisto en que no es buena idea hacer que el escritorio cambie constantemente su fondo. El escritorio es la ventana 0, todo el resto del IDE de windows cuelga de él, es la raíz. Cualquier sobrecarga en el uso o refresco del escritorio, supone un lastre para el resto. Piensa que otro agravio en la lentitud, es que el escritorio ha de recortar todos los elementos que contiene para pegar la imagen... Si al menos estuviera vacío... se evitaría el recorte, pero claro entonces no se distinguiría de un 'salvapantallas'... Como mínimo en tu bucle o bien pones un intervalo alto entre cambio de imágenes... o que se detenga cuando descubra que otros procesos (que no son el tuyo), consumen/demandan recursos del procesador... Gracias bro, voy a dejar la idea de cambiar constantemente el fondo de pantalla. e intentare dibujar directamente en el escritorio , debajo de los iconos. es muchísimo mas rapido, y no sobrecarga el escritorio.
|
|
|
En línea
|
|
|
|
**Aincrad**
|
Solucionado!
Tuve que convertir mucho código de c++ y c# a vb , pero valio la pena : Solo faltan algunos ajustes.
|
|
« Última modificación: 18 Mayo 2021, 20:00 pm por **Aincrad** »
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
swf como fondo de escritorio
Diseño Gráfico
|
wACtOr
|
5
|
4,326
|
11 Marzo 2005, 03:00 am
por wACtOr
|
|
|
Cómo convertir jpg en fondo de escritorio.
Diseño Gráfico
|
helejagy
|
9
|
3,593
|
15 Septiembre 2006, 22:34 pm
por SirLanceCC
|
|
|
como añadir un fondo de escritorio a un formulario en java
Java
|
inforelectro
|
1
|
4,899
|
2 Agosto 2008, 00:00 am
por ~~
|
|
|
¿editar .swf y ponerlo como fondo de escritorio en windows 7?
Diseño Gráfico
|
Kurolox
|
6
|
8,991
|
24 Noviembre 2012, 17:39 pm
por Kurolox
|
|
|
Establecer Vídeo como fondo de Escritorio (Programa).
Programación C/C++
|
ProxyCarinae
|
2
|
2,993
|
3 Octubre 2017, 17:54 pm
por ProxyCarinae
|
|