Como Guardar una imagen creada "_GDIPlus"

Pregunta Sin Miedo no te cortes cualquier cosa para empezar - Autoit se comienza facilmente.Para Ordenes o Comandos sueltos. Ver nota como preguntar.
Responder
dacu
Hacker del Foro
Mensajes: 106
Registrado: 20 May 2010, 00:09

Como Guardar una imagen creada "_GDIPlus"

Mensaje por dacu »

Hola buenas.

Estoy generando una imagen con

Código: Seleccionar todo

    GUICreate
				_GDIPlus_Startup ()
				$hGraphic = _GDIPlus_GraphicsCreateFromHWND ($hGUI)
				$blanco =_GDIPlus_BrushCreateSolid(0xffffffff)
							_GDIPlus_GraphicsFillRect...............
Pero no se como la puedo guardar.

Digamos que el scrip me genera una imagen en la propia gui y quiero capturar ese contenido y guardarlo en formato foto, pero sin hacer un captura de pantalla.

Gracias.
Avatar de Usuario
arkcrew
Profesional del Autoit
Mensajes: 506
Registrado: 28 Sep 2009, 19:17
Ubicación: Granada, España
Contactar:

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por arkcrew »

Has probado la función _GDIPlus_ImageSaveToFile()??

Tienes más info en la ayuda.

Saludos!!
dacu
Hacker del Foro
Mensajes: 106
Registrado: 20 May 2010, 00:09

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por dacu »

gracias por contestar, pero Mira.

si analizo:

Código: Seleccionar todo

$hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap1)
Veo que viene de aquí:

Código: Seleccionar todo

$hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap1)
Que a la vez viene de:

Código: Seleccionar todo

$hBitmap1 = _ScreenCapture_Capture("")
Llegamos a un captura de escritorio y no quiero eso, quiero una imagen creada desde 0 desde autoit y guardarla.

Lo mas seguro es que sea con esa misma función pero aplicándola de otra forma.
Avatar de Usuario
arkcrew
Profesional del Autoit
Mensajes: 506
Registrado: 28 Sep 2009, 19:17
Ubicación: Granada, España
Contactar:

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por arkcrew »

Bueno , he mirado asi un porquito y creo que debe ser con esa función, es lo más que google me da con "save an image created using gdi autoit", te linkeo las webs que he encontrado interesantes.

http://www.autoit.de/index.php?page=Thr ... adID=19702 (mira los spoliers que es donde están los codes)
http://www.autoitscript.com/forum/topic ... e-to-file/
http://www.autoitscript.com/forum/topic ... mage-save/

Espero que te ayuden en algo ya que yo no soy experto en esa librería..

Saludos!!
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por Ximorro »

Creo que tienes que crear el bitmap a partir del Graphics.
Y para guardarlo tienes que crear el handle a ese bitmap:

Código: Seleccionar todo

$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hbmpGraph = _GDIPlus_BitmapCreateFromGraphics($anchoGui,$altoGui, $hGraphic)
$BMP = _GDIPlus_BitmapCreateFromHBITMAP($bmpGraph)
_GDIPlus_ImageSaveToFile($BMP, $path)
Fíjate que tienes que poner el tamaño a la hora de crear el bitmap, según el tamaño del GUI.

El pequeño lío que tengo es que según la ayuda _GDIPlus_BitmapCreateFromGraphics a pesar del nombre no crea un BITMAP, sino un HBITMAP (un handle al bitmap), y no tengo claro lo que necesita _GDIPlus_ImageSaveToFile, porque la ayuda dice "un handle a una imagen" pero recuerdo que tuve problemas con eso, así que pasaba el BITMAP a HBITMAP con _GDIPlus_BitmapCreateFromHBITMAP para que funcionara.
Así que usa eso, y si no funciona prueba a saltarte el paso de BitmapCreateFromHBITMAP, guardando directamente hbmpGraph. Si eso no funciona pues nos lo dices y seguimos investigando.

Por cierto, recuerda destruir correctamente todos los objetos antes del _GDIPlus_Shutdown()
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por Ximorro »

Bueno, pues directamente no he podido. Era sin el BitmapCreateFromHBITMAP, pero de todas maneras crea un bitmap vacío. Compatible con el Graphics del GUI, pero vacío.
La única manera de conseguir esto ha sido precisamente al revés: dibujo en el bitmap vacío generado a partir del GUI, para que se vea en el GUI copio ese bitmap en su Graphics. Así puedo guardar el bitmap (he dibujado en él a través de su GraphicsContext)

Por favor, la próxima vez ponnos un trozo de código con el que poder empezar a trabajar.
Aquí va el mío siguiendo el esquema que he comentado antes. Ojo con los Dispose, que no falte ninguno.

Código: Seleccionar todo

#Include <GDIPlus.au3>
$gui = GuiCreate("Imagen GDI+", 300, 200)
GUISetState()

_GDIPlus_StartUp()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($gui)
$bmpGraph = _GDIPlus_BitmapCreateFromGraphics(300,200, $hGraphic)
$bmpCtx = _GDIPlus_ImageGetGraphicsContext($bmpGraph)
_GDIPlus_GraphicsClear($bmpCtx, 0xFFFF0000)

$blanco =_GDIPlus_BrushCreateSolid(0xffffffff)
_GDIPlus_GraphicsFillRect($bmpCtx, 50, 50, 100, 100, $blanco)

_GDIPlus_GraphicsDrawImageRect($hGraphic, $bmpGraph, 0,0, 300,200)

_GDIPlus_ImageSaveToFile($bmpGraph, "D:\imagen.png")

Sleep(1000)

_GDIPlus_GraphicsDispose($bmpCtx)
_GDIPlus_BitmapDispose($bmpGraph)
_GDIPlus_BrushDispose($blanco)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_ShutDown()
Si te sirve así genial, pero como digo lo contrario no lo he conseguido: sacar un bitmap de un Graphics de un GUI donde ya se ha dibujado y guardarlo.
He probado clonando el bitmap con _GDIPlus_BitmapCloneArea y tampoco. ¿Quizás habrá que bloquear los bits para poder leerlos?
Si alguien puede arrojar más luz...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por Ximorro »

Ya estoy aquí otra vez.
Pues parece que la solución directa está complicada. La siguiente explicación del usuario Authenticity del foro inglés es muy aclaratoria. La traduzco debajo:

"Each Image object stores a Graphics object that defines any transformations, scaling, etc.. of the Image object. A Bitmap object is a descendant of the Image class so you can consider a Bitmap to be an Image object. When you create a Bitmap object from a Graphics object, you just create a Bitmap object that it's Graphics object is defined by the supplied Graphics object. This Graphics object does not contain anything but the properties (transformations, etc..) of the defining Graphics object."

"Cada objeto Image almacena un objeto Graphics que define las transformaciones, escala, etc. del objeto Image. Bitmap es descendiente de la clase Image por lo que puedes considerar un objeto Bitmap como si fuera un objeto Image. Cuando se crea un objeto Bitmap desde un objeto Graphics, sólo se crea un objeto Bitmap tal que su objeto Graphics está definido por el objeto Graphics especificado. Este objeto Graphics no contiene nada más que las propiedades (transformaciones, etc.) del objeto Graphics original."

Está aquí:
http://www.autoitscript.com/forum/topic ... _p__806778

Es decir, al crear el Bitmap a partir del Graphics del GUI con _GDIPlus_BitmapCreateFromGraphics, no estamos copiando los datos de la imagen (los pixeles) sino SOLAMENTE los parámetros de transformación. Es un bitmap de exactamente el mismo tipo que el del GUI ¡pero vacío!
Es lo que ya había experimentado pero aquí nos lo aclara y explica.

Así que si no te sirve mi sistema inverso si quieres tomar esos datos por ahora sólo se me ocurre recurrir temporalmente a WinAPI y capturar de forma similar a como hace _ScreenCapture_Capture creando bitmap compatible a través del DC de la ventana, y copiando con _WinAPI_BitBlt.
Ese bitmap compatible se puede trasformar en GDI+ con _GDIPlus_BitmapCreateFromHBITMAP ¡ahora sí! :smt003 y eso ya se puede guardar con _GDIPlus_ImageSaveToFile.

Supongo que habrá una manera de hacerlo totalmente desde GDI+, si alguien la conoce...
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
dacu
Hacker del Foro
Mensajes: 106
Registrado: 20 May 2010, 00:09

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por dacu »

Buenas Ximorro y arkcrew Por la ayuda.

Voy a exponer lo que conseguí ayer, "que ami parecer es un poco chapucero"

Mediante un ScreenCapture lo tape todo de un color y escribí encima de eso.

Código: Seleccionar todo

	    _GDIPlus_Startup()
	$hBitmap1 = _ScreenCapture_Capture("", 0, 0, $xlargo, $ylargo) ; Captura pantalla
    $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap1)

	$ColorFondo =_GDIPlus_BrushCreateSolid(0xffffffff) ; Color Blanco
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1)   ; ....... Pinta de blanco
	_GDIPlus_GraphicsFillRect($hGraphic, 0, 0, $xlargo + 1, $ylargo + 1,$ColorFondo) ; ....... Pinta de blanco
Luego ya, hay puedo hacer lo que quiera.

Código: Seleccionar todo

		$hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1)   ; ....... Pinta de blanco
			_GDIPlus_GraphicsDrawString($hGraphic, $string[$contadorString], $x, $y,"Verdana") ; ESCRIVE LA LETRA QUE ENCUENTRA
_GDIPlus_ImageSaveToFile($hImage1,@ScriptDir & "\1.bmp") ; Guarda la foto

De todas formas, voy a aplicar las formas que me habéis expuesto y ver que resultados obtengo.

Muchas gracias.

"aclaro que mi ingles es nulo, por eso me cuesta tanto ciertas cosas".
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por Ximorro »

¡Pero hombre, para eso crea el bitmap con _GDIPlus_BitmapCreateFromGraphics!
Es un bitmap compatible con el del GUI, te ahorras copiar la pantalla (que de todas maneras no utilizas) ¡y no te sales de GDI+! (la captura de pantalla se hace con WinApi.
Es lo que te he puesto hace dos comentarios ¡con el código completo!

Otra cosa es que sí quieras capturar la pantalla, o un trozo de ella, para trabajar con esa información. Es lo que te decía en el último comentario. Puedes usar _ScreenCapture_Capture como has hecho o más directamente con el DC de la ventana y _WinAPI_BitBlt (puedes ver el código de _ScreenCapture_Capture y simplificarlo).
En cualquier caso el tipo de imagen de WinAPI es diferente al de GDI+ (creo que WinAPI usa el antiguo GDI, sin el "plus") así que en cualquier caso hay que hacer la conversión con BitmapCreateFromHBITMAP.
Para un programa que usa bastante estas cosas puedes ver mi capturador:
http://www.emesn.com/autoitforum/viewto ... f=5&t=1848

Para lo de GDI+ mírate bien el código que te puse.
Respecto al tuyo:
Pones un código parcial así que no sé cómo lo has completado, asegúrate de liberar los objetos al final del programa, en el orden adecuado, antes de _GDIPlus_Shutdown()
Para inicializar el bitmap en vez de rellenarlo con un rectángulo con un brush sólido es más eficiente hacer un _GDIPlus_GraphicsClear, además te ahorras el brush.
Por si acaso te ha confundido el contexto para dibujar (_GDIPlus_ImageGetGraphicsContext) sólo hay que tomarlo una vez, no antes de cualquier operación de dibujo.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por Chefito »

Hola chicos.
Como siempre Ximorro me sorprende con sus soluciones :smt002 .

A mí, antes de decir nada, me gustaría que me aclarase algo dacu. Tengo varias preguntas sobre que es exactamente lo que quieres hacer y como lo haces.
Quieres capturar todo el gui (con la ventana incluida)??? Eso se puede hacer de varias formas, pero supongo que la más facil es haciendo la captura de la ventana con la combinación de teclas ctrl+alt+impr pant y luego recuperarla del portapapeles. Supongo que esto no vale

Ahora vamos a las buenas:
Cuando dices que dibujas directamente sobre el gui (puede ser pero lo dudo), donde dibujas exactamente??? En el propio gui o utilizas un objeto pic (GUICtrlCreatePic) o graphic (GUICtrlCreateGraphic)??? Puede que se pueda trabajar directamente con estos objetos.

Como dice Ximorro, si nos pones los códigos completos y funcionales vemos mejor que estás haciendo, y que soluciones puede haber. Puede que tu problema se pueda solucionar de alguna forma más facil que la propuesta inicialmente. Suele haber varias soluciones para un mismo problema, algunas más faciles y otras más complicadas.

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por Chefito »

Al final me ha picado un poco la curiosida de esto que estais haciendo, aunque sigo sin saber si es como debería hacerse....pero bueno.

Como dice Ximorro, con la WinApi se puede realizar esto (vamos, con la api de windows). Os muestro un código sacado practicamente entero de la función _ScreenCapture_Capture. Mirarla.

Código: Seleccionar todo

#Include <GDIPlus.au3>
#Include <WinAPI.au3>
#Include <WindowsConstants.au3>

$gui = GuiCreate("Imagen GDI+", 300, 200)
$Button_1 = GUICtrlCreateButton("Run Notepad", 10, 30, 100)
$Button_2 = GUICtrlCreateButton("Button Test", 30, 70)

GUISetState()
_GDIPlus_Startup ()
Local $hDDC = _WinAPI_GetDC($gui)
Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
Local $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, 300, 200)
_WinAPI_SelectObject($hCDC, $hBMP)
_WinAPI_BitBlt($hCDC, 0, 0, 300, 200, $hDDC, 0, 0, $SRCCOPY)
$hImage = _GDIPlus_BitmapCreateFromHBITMAP ($hBMP)
_GDIPlus_ImageSaveToFile($hImage, "C:\imagen.png")

_WinAPI_ReleaseDC($gui, $hDDC)
_WinAPI_DeleteDC($hCDC)
_WinAPI_DeleteObject($hBMP)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_ShutDown()
También es interesante _ScreenCapture_CaptureWnd para cosas de este tipo.

Tiene que haber un montón de formas de hacer esto. Pensad que el gdi+ no se acaba en la librería gdiplus. Recordar que tenemos la GDIP.au3, que implementa un montón de funciones gpi que le faltan a la que trae autoit. También tenemos la WinApiEx.au3, extensión de la WinApi que trae autoit. Lo dicho, se podrá hacer de muchas formas más :smt003 .

Saludos.
Última edición por Chefito el 25 Ene 2012, 18:12, editado 1 vez en total.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
dacu
Hacker del Foro
Mensajes: 106
Registrado: 20 May 2010, 00:09

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por dacu »

Madre mía. Tengo que admitir que soy un poco chapucero.

Este es el código que hice hace unos días. Pero visto lo visto, cambiare muchas opciones que me habéis escrito.

Tenéis que crear un archivo que se llame "datos.txt" -- Escribir los caracteres que queráis y luego os saldrá en la imagen XD

Código: Seleccionar todo

#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>



;Este script convertirá el texto del archivo en Imagenes

Todo()
Func Todo()

	Global $file= FileOpen("datos.txt") ;Archivo a escanear
	Global $leer= FileRead($file) ;Leer ARCHIVO
	Global $string = StringSplit($leer, "")

	$xlargo = 500
	$ylargo = 500
	$x = 0
	$y = 0

	    _GDIPlus_Startup()
	$hBitmap1 = _ScreenCapture_Capture("", 0, 0, $xlargo, $ylargo) ; Captura pantalla
    $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap1)

	$ColorFondo =_GDIPlus_BrushCreateSolid(0xffffffff) ; Color Blanco
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1)   ; ....... Pinta de blanco
	_GDIPlus_GraphicsFillRect($hGraphic, 0, 0, $xlargo + 1, $ylargo + 1,$ColorFondo)


	$C_Wile=1 ;variable While
	$contadorString=1 ; Contador string

	While $C_Wile <= $string[0]

		$hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1)   ; ....... Pinta de blanco

					_GDIPlus_GraphicsDrawString($hGraphic, $string[$contadorString], $x, $y,"Verdana") ; ESCRIBE LA LETRA QUE ENCUENTRA
					$C_Wile = $C_Wile + 1

		$contadorString= $contadorString +1

		  $x += 20
		  If $x = $xlargo Then
			 $x = 0
			 $y += 15
			 If $y = $ylargo then exitloop
		 EndIf

	WEnd

				_GDIPlus_ImageSaveToFile($hImage1,@ScriptDir & "\1.bmp") ; Guarda la foto

EndFunc


Perdón por el desastre de código y lineas que no tendrán sentido.
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por Ximorro »

Respecto al código de Chefito: EXACTAMENTE a eso me refería. No lo puse a ver si dacu se animaba y lo hacía pero te has adelantado. :smt005

dacu, efectivamente si hubieras dicho más concretamente qué buscabas podíamos haberte ayudado mejor. Al principio parece que querías dibujar en el GUI y luego guardarlo a archivo (la primera opción que te puse era una posibilidad), pero parece que efectivamente ya tenías algo en el GUI y eso lo querías guardar (es la segunda opción con BitBlt, como el código de Chefito.
En realidad para lo del texto también se puede hacer con la primera opción, si escribes el texto con GDI+ en el bitmap, pero es más complicado... anda si es lo que intentas en el código, pues vamos a comentarlo:

Un par de cositas que no tienen que ver con los gráficos:
Si metes el código en una función, no crees variables globales, dentro de la función son locales...
Ojo que no has cerrado el archivo txt.

Modifícalo teniendo en cuenta los comentarios anteriores y tendrás un buen código, principalmente:
.- No hay que capturar la pantalla si no vas a usarla, mejor creas simplemente un bitmap compatible a partir del GUI.
.- _GDIPlus_ImageGetGraphicsContext ¡¡no pinta de blanco!!, el contexto de una imagen es un objeto que se usa para dibujar en ella. Como te decía en un comentario anterior ¡sólo debes asignarlo una vez!, no cada vez que vayas a dibujar (no dentro del bucle). Para pintar de blanco (o cualquier relleno sólido) usa _GDIPlus_GraphicsClear como en mi ejemplo, mucho mejor que pintar un rectángulo (más rápido y no usa un brush).
.- Importantísimo: ¡Libera y destruye los objetos al final! Los de GDI+ con las funciones Dispose correspondientes. Y si acabas usando la API de Windows (la llamo WinApi por la udf de AutoIt :smt003 ) con los Release o Delete. Fíjate en nuestros dos ejemplos.

Tal como lo tienes, escribiendo con _GDIPlus_GraphicsDrawString, no te hace falta pasar a WinAPI para capturar la ventana, lo haces todo con GDI+.
Pero lo de WinAPI también es una opción muy interesante porque te permitiría escribir el texto en un objeto label normal, donde puedes dar formato muy fácilmente, y luego capturarlo. Si te pones a hacer algo más complicado con los textos en GDI+ verás lo complicado que puede llegar a ser... se hace con _GDIPlus_GraphicsDrawStringEx, aquí un ejemplo del trozo para escribir un simple label a ver si consigo asustarte:

Código: Seleccionar todo

$hBrushLbl = _GDIPlus_BrushCreateSolid(0xFF000000)
$hFormat = _GDIPlus_StringFormatCreate()
$hFamily = _GDIPlus_FontFamilyCreate("Microsoft Sans Serif")
$hFont = _GDIPlus_FontCreate($hFamily, 8.6, 0)
$hFontNeg = _GDIPlus_FontCreate($hFamily, 8.6, 1) ;versión negrita
$lbl1 = "El texto a escribir"
$aInfo1 = _GDIPlus_GraphicsMeasureString($hGraphic, $lbl1, $hFontNeg, _GDIPlus_RectFCreate(22, 68, 0, 0), $hFormat)
$aInfo1 = $aInfo1[0]
_GDIPlus_GraphicsDrawStringEx($ctxBuffer, $lbl1, $hFontNeg, $aInfo1, $hFormat, $hBrushLbl)

_GDIPlus_FontDispose($hFont)
_GDIPlus_FontDispose($hFontNeg)
_GDIPlus_FontFamilyDispose($hFamily)
_GDIPlus_StringFormatDispose($hFormat)
_GDIPlus_BrushDispose($hBrushLbl)
Es una extracción de lo que usé en mi GUI con fondo animado con GDI+
http://www.emesn.com/autoitforum/viewto ... f=4&t=2302
En la cuarta versión, que es la buena. Fue una pesadilla...


¡Gracias por poner el código! Si lo hubieras puesto al principio ya nos habríamos enfocado en ese problema concreto.
Ya nos dices si tienes problemas para hacer las modificaciones que te sugerimos (si te parecen bien, claro, pero piensa que algunas son por errores y deberías hacerlas).
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por Ximorro »

Chefito tengo una duda con tu código:
Cuando haces el BitmapCreateFromHBITMAP reutilizas la variable $hBMP con lo que el primer handle queda sin referenciar.
La duda es al liberar el objeto. ¿Realmente son dos handles para el mismo objeto y basta liberarlo con uno de ellos? ¿o se ha hecho una reconversión de objeto y habría que liberar los dos?
No lo tengo muy claro pero me temo que es lo segundo pues hasta donde tengo entendido WinAPI trabaja con objetos GDI, y GDI+ puessss con GDI PLUS ;-). Pueden ser compatibles pero no es el mismo objeto.

Mirando un poco más ScreenCapture tengo más claro que hay que liberar los dos. Si nos fijamos en _ScreenCapture_Capture tenemos:

Código: Seleccionar todo

$hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iW, $iH)
...
_ScreenCapture_SaveImage($sFileName, $hBMP)
_WinAPI_DeleteObject($hBMP)
Eso es WinAPI, pero en esa _ScreenCapture_SaveImage es cuando usa GDI+ para guardar en disco:

Código: Seleccionar todo

$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap) ;En $hBitmap está el anterior $hBMP que ha llegado como parámetro
...
_GDIPlus_ImageDispose($hImage)
Dentro de la función opcionalmente también libera $hBitmap con _WinAPI_DeleteObject, pero de todas maneras como veíamos lo hace fuera desde _ScreenCapture_Capture después de la llamada a _ScreenCapture_SaveImage.

Conclusión:
Me parece que el handle creado con _WinAPI_CreateCompatibleBitmap hay que liberarlo con _WinAPI_DeleteObject y el creado a partir de él con _GDIPlus_BitmapCreateFromHBITMAP hay que liberarlo con _GDIPlus_ImageDispose.

Por lo demás tu código es una maravilla. ¡Ha vuelto el amo de la API de Windows! ¡Bieeeeeen! :smt026


dacu, léete bien y con tranquilidad todos los comentarios, comprendo que algunos son un lío pero que creo que los pasaste demasiado rápido.
Si no entiendes algo pregunta, no te preocupes. Yo estaré por aquí pero eso sí, que conste que no soy muy experto en GDI+, ¡en realidad lo odio! :smt003 pero en el foro hay gente que ha hecho cosas bastante avanzadas así que si no sé yo alguien podrá ayudar.
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Avatar de Usuario
Chefito
Profesional del Autoit
Mensajes: 2035
Registrado: 21 Feb 2008, 18:42
Ubicación: Albacete/Cuenca (España)

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por Chefito »

Jejejeje.....Ximorro, menos mal que está siempre ahí para corregirme :smt002 . Pues sí, un gran fallo del que no me di cuenta. Como empezé ha hacerla (Hize casi todo pero no me acordé de la api createobject, por eso no me salía), luego me acordé de que podía estar la solución en la udf screencapture, y no me molesté mucho ya que hice casi todo con copia-pega, pues eso se me pasó.
Pues eso, que tienes razón, que machaco el valor de esa variable que hace referencia a el objeto, y ese objeto queda sin destruir. Supongo que se destruirá al salir del programa, pero como yo siempre digo, hay que hacer las cosas bien.
El código de mi post anterior ya ha sido corregido y editado :smt002 . Gracias.
Ximorro escribió:Por lo demás tu código es una maravilla. ¡Ha vuelto el amo de la API de Windows! ¡Bieeeeeen!
Jejeje, nunca me fuí. Yo suelo mirar todos los correos. Lo único que no ayudo tanto.
El lunes entregé mi práctica en java con la memoria, pruebas y demás, y como estoy de vacaciones pues me puse a hacer algún código en autoit. La práctica me ha quedado bastante chula :smt002 . Ahora vienen los exámenes :smt022 .

Jejejeje y lo del amo de las apis ya me lo has quitado tú :smt005 .

Dacu, respecto a lo que estás intentando hacer, haz caso a Ximorro. Yo lo haría como dice. Lo haría todo por gpi+, ayudado de alguna api de win si es necesario. Crea tu zona de dibujo con un objeto gdi+, en vez de directamente en la ventana. Mira los ejemplos y verás que lo que intentas no es tan dificil.

Saludos.
Cita vista en algún lugar de la red: En este mundo hay 10 tipos de personas, los que saben binario y los que no ;).
Avatar de Usuario
Ximorro
Profesional del Autoit
Mensajes: 1500
Registrado: 10 Jul 2009, 12:35
Ubicación: Castellón, España

Re: Como Guardar una imagen creada "_GDIPlus"

Mensaje por Ximorro »

Al cambiar la variable te ha faltado usar $hImage en el _GDIPlus_ImageSaveToFile, que se ha quedado con la variable vieja $hBMP que ahora referencia al bitmap GDI (sin plus).
Ya te lo cambio yo.

¡Suerte con los exámenes!
"¿Y no será que en este mundo hay cada vez más gente y menos personas?". Mafalda (Quino)
Responder