Página 1 de 1

ayuda para mover una imagen png con gdi+

Publicado: 09 Dic 2010, 09:25
por adrmil
:smt039
hola.. es mi primer pregunta en este foro soy algo tímida, llevo visitándolo desde hace tiempo mas de 1 año jeje, no me habia animado a preguntar espero me puedan ayudar.

después de ver ejemplos con _GDIPlus probar y ver ejemplos acá en el foro, veo que es muy complicado de manejar.

e probado con los ejemplos que trae el archivo de ayuda de autoit, y no se como hacer para mover una imagen dentro de la misma ventana.

:smt017

Código: Seleccionar todo

#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>

Global $hGUI, $hImage, $hGraphic

$hGUI = GUICreate("Show PNG", @DesktopWidth, 240)
GUISetState()

_GDIPlus_StartUp()
$hImage   = _GDIPlus_ImageLoadFromFile("Torus.png")

$o = 10
AdlibRegister("blabla", 10)

do
until GUIGetMsg() =$GUI_EVENT_CLOSE
_GDIPlus_ImageDispose($hImage)
_GDIPlus_Shutdown()

_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_ShutDown()

Func blabla()
	$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
_GDIPlus_GraphicsDrawImage($hGraphic, $hImage, $o, 0)
;~ _GDIPlus_GraphicsClear($hGraphic)
$o = $o + 2
EndFunc
tambien
:smt024
intente colocar la imagen con la ventana transparente y con movimiento, pero es mas complicado todavía.
utiliza una funcion:

Código: Seleccionar todo

Func SetBitmap($hGUI, $hImage, $iOpacity)
que esta en los archivos de ejemplo de autoit se llama "ShowPNG.au3"

C:\Program Files\AutoIt3\Examples\GUI\Advanced\ShowPNG.au3

gracias ojala me puedan ayudar. :smt005

bye.

Re: ayuda para mover una imagen png con gdi+

Publicado: 10 Dic 2010, 00:45
por gesher
:smt017

Re: ayuda para mover una imagen png con gdi+

Publicado: 11 Dic 2010, 09:12
por adrmil
gracias.... pero con gif se puede hacer de todo :smt021 lo que busco es con png. el ejemplo también lo conocía, quiero mover el png dentro de la ventana que después coloco transparente, con el fin de hacer un gadget para windows 7, con gif se ve feíto :smt005

espero me puedan ayudar muchas gracias.

Re: ayuda para mover una imagen png con gdi+

Publicado: 13 Dic 2010, 12:52
por Ximorro
Bienvenida adrmil, me alegro a que te hayas decidido a intervenir activamente ¡aunque el tema se las trae! ;-)

Yo no soy un gran experto de GDI+, en realidad sólo he hecho algunos experimentos, y la verdad, GDI+ me parece tan engorroso de manejar que no me gusta nada.

Pero bueno, si a mover la imagen te refieres más o menos a lo que hice con mi GUI con las bolas animadas en el fondo, te puedo hacer una simplificación de aquéllo con esta imagen. La verdad es que si no hay controles estándar que dibujar, sólo la imagen, es muchísimo más fácil. Te pongo dos versiones, la primera es la más simple, dibujando directamente en el canvas (lienzo) del formulario. El problema es que como puedes comprobar parpadea al dibujar el toro.
En la segunda versión con búfer dibujo en una imagen en segundo plano ($hBuffer), y luego eso se pasa al GUI, así es más fluido, aunque no es que sea perfecto.
Eso sí, no hunde para nada la CPU, a mí en un ordenador intermedio no me llega al 2% de carga, de todas maneras si te salta mucho cambia la frecuuencia de AdlibEnable, ¡y por cierto, si usas la última versión de AutoIt cambia AdlibEnable por AdlibRegister!.

He dejado comentadas las líneas que hacen referencia a WM_PAINT, eso sólo es necesario para interactuar con el pintado de controles estándar (botones, etiquetas). Si no tienes que poner controles sobre la imagen no hace falta, y espero que no haga falta porque es mucho más complicado hacerlo suave, en ese caso te remito al tema de "Fondo con bolas animadas"
http://www.emesn.com/autoitforum/viewto ... 02&start=0

El tamaño de la imagen lo averiguo por código, eso te interesará mirarlo.

Por cierto, he recortado la imagen del toro porque tiene espacios en blanco a los lados, con lo que el tamaño de la imagen no correspondía con el tamaño del contenido (y no me rebotaba en los bordes del GUI). He adjuntado la imagen modificada con los scripts.

Por cierto, prefiero _GDIPlus_GraphicsDrawImageRect en vez de _GDIPlus_GraphicsDrawImage para dibujar el toro, porque este último no respeta el tamaño inicial ¿?

Lo de la transparencia no lo he mirado, ¿qué quieres decir, que el GUI tenga fondo transparente?
Sobre eso no investigué, mi problema eran los controles transparentes (etiquetas y cosas así) sobre mi imagen, es un tema muy diferente. Intenta hacer algo sobre esta animación (si te sirve) y nos dices.

Re: ayuda para mover una imagen png con gdi+

Publicado: 13 Dic 2010, 14:31
por Ximorro
He conseguido hacer el fondo de la ventana transparente gracias a la función SetLayeredWindowAttributes de user32.dll (uso una "envoltura" para AutoIt de ProgAndy, sacado del foro inglés, aunque la función no es que sea suya, como digo está en user32.dll)

El problema es cuando el PNG tiene semitransparencias, como este (la sombra). Si no tiene semitransparencias, que es coger sólo un color de fondo y hacerlo transparente ¡ya está!.
Si hay que hacer que las semitransparencias del png también se trasladen a lo que haya detrás del GUI no tengo ni idea...

Este es el código por ahora, uso el png modificado que puse en el post anterior:

Código de ToroAnimadoBufferTrans.au3

Código: Seleccionar todo

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <GDIPlus.au3>

Opt("MustDeclareVars", 1)

Global $ToroGUI, $btnCerrar
Global $anchoG = 300, $altoG = 300, $cFondoG = 0xECE9E0, $cFondo = BitShift(0xFF,-24)+$cFondoG
Global $hImage, $anchoImg, $altoImg, $X=0,$vX=5, $Y=0,$vY=5, $vmin=1,$vmax=5

$ToroGui = GUICreate("Toro animado", $anchoG, $altoG, -1,-1, -1, $WS_EX_LAYERED)
GUISetBkColor($cFondoG)
_WinAPI_SetLayeredWindowAttributes($ToroGUI, $cFondoG,255,1)

_GDIPlus_StartUp()
Global $hGraphic, $hBmp, $hBuffer, $ctxBuffer
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($ToroGui)
$hBuffer = _GDIPlus_BitmapCreateFromGraphics($anchoG,$altoG, $hGraphic)
$ctxBuffer = _GDIPlus_ImageGetGraphicsContext($hBuffer)

$hImage = _GDIPlus_ImageLoadFromFile("Torus.png")
$anchoImg = _GDIPlus_ImageGetWidth($hImage)
$altoImg = _GDIPlus_ImageGetHeight($hImage)
;ConsoleWrite($anchoImg & " " & $altoImg & @LF)

GUIRegisterMsg($WM_PAINT, "MY_WM_PAINT")
;WinSetTrans($ToroGUI, "", 255)
GUISetState(@SW_SHOW)

AdlibEnable("_MueveImagen", 20)

While 1
	Switch GUIGetMsg()
		Case $GUI_EVENT_CLOSE
		ExitLoop
	EndSwitch
WEnd

AdlibDisable()

_GDIPlus_BitmapDispose($hImage)
_GDIPlus_GraphicsDispose($ctxBuffer)
_GDIPlus_BitmapDispose($hBuffer)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_ShutDown ()

Func _MueveImagen()
	_GDIPlus_GraphicsClear($ctxBuffer, $cFondo)

	$X += $vX
	If $X+$anchoImg > $anchoG Then
		$X = $anchoG-$anchoImg
		$vX = -Random($vmin,$vmax,1)
	ElseIf $X < 0 Then
		$X = 0
		$vX = Random($vmin,$vmax,1)
	EndIf
	$Y += $vY
	If $Y+$altoImg > $altoG Then
		$Y = $altoG-$altoImg
		$vY = -Random($vmin,$vmax,1)
	ElseIf $Y < 0 Then
		$Y = 0
		$vY = Random($vmin,$vmax,1)
	EndIf

	_GDIPlus_GraphicsDrawImageRect($ctxBuffer, $hImage, $X,$Y, $anchoImg,$altoImg)
	_GDIPlus_GraphicsDrawImage($hGraphic, $hBuffer, 0, 0)
	_WinAPI_RedrawWindow($ToroGui, 0,0, $RDW_INTERNALPAINT)
EndFunc

Func MY_WM_PAINT($hWnd, $Msg, $wParam, $lParam)
	_WinAPI_RedrawWindow($ToroGui, 0, 0, $RDW_INVALIDATE)
	Return $GUI_RUNDEFMSG
EndFunc

Func _WinAPI_SetLayeredWindowAttributes($hwnd, $i_transcolor, $Transparency = 255, $dwFlages = 0x03, $isColorRef = False)
    If $dwFlages = Default Or $dwFlages = "" Or $dwFlages < 0 Then $dwFlages = 0x03

    If Not $isColorRef Then
        $i_transcolor = Hex(String($i_transcolor), 6)
        $i_transcolor = Execute('0x00' & StringMid($i_transcolor, 5, 2) & StringMid($i_transcolor, 3, 2) & StringMid($i_transcolor, 1, 2))
    EndIf
    Local $Ret = DllCall("user32.dll", "int", "SetLayeredWindowAttributes", "hwnd", $hwnd, "long", $i_transcolor, "byte", $Transparency, "long", $dwFlages)
    Select
        Case @error
            Return SetError(@error, 0, 0)
        Case $Ret[0] = 0
            Return SetError(4, _WinAPI_GetLastError(), 0)
        Case Else
            Return 1
    EndSelect
EndFunc   ;==>_WinAPI_SetLayeredWindowAttributes