Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Gráficos
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 26-12-2010
Avatar de Marck Silencer
Marck Silencer Marck Silencer is offline
Registrado
 
Registrado: Dec 2010
Posts: 7
Poder: 0
Marck Silencer Va por buen camino
Question Liberación de memoria de Tbitmap

Hola! a todos los miembros de este genial foro!! Soy nuevo en el Foro espero también ayudar en lo que se pueda por aqui.

Mientras tanto tengo un problema que me ah traido de cabeza bastantes horas y aún no eh podido resolver. Ya eh buscado por todas partes e incluso Post de éste mismo foro me han servido para ir avanzando con mi programa pero aún estoy atorado .

Una breve descripción de lo que busco con el programa...Requiero estar constantemente scaneando los pixeles una determinada área de la pantalla para obtener el color predominante en dicha área para despues seguir con más codigo utilizando ese color predominante. Hasta el momento eh conseguido el color de un solo pixel en la pantalla y de momento lo muestro cambiando el color de un panel... Tódo esto lo hago en un timer ajustado a 10 ms.....

Funciona correctamente va cambiando el color de panel según que color pase por ese pixel que estoy escaneando, el problema es que despues de un tiempo de estar escaneando y mostrandolo en la propiedad de color del panel, Se detiene la ejecución mostrandome un error "EoutOfResources" y realizando antes unas modicaciones al código me salía otro error acerca de que el Tcanvas no puede "dibujar".....

Creoo que mi error está en el modo de scanear oh en el modo de liberar la memoria o los handles que usal el TBitmap.....!! Ya eh intentando demaciadas cosas sin lograr que pueda escanear sin tiempo definido ese pixel..... Creo yo que debe de existir una forma en la cual se haga el escaneo -> Se liberen los recursos utilizados -> Volver a escanear con esos mismos recursos........así no pasaría esto!( segun entiendo claro) xD

Aqui pongo el código que estoy utilizando.

Código Delphi [-]
implementation
var
myColor:TColor;
Pxl  : TBitmap;
{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Pxl:=TBitmap.Create;
Pxl.Width:=1;
Pxl.Height:=1;
Pxl.Dormant;
 Try
BitBlt(Pxl.Canvas.Handle,0,0,1,1,GetDC(0),123,123,SRCCOPY);
myColor:=Pxl.Canvas.Pixels[0,0];
panel1.Color:= myColor;
 finally
 Pxl.FreeImage;
 Pxl.ReleaseHandle;
 Pxl.ReleaseMaskHandle;
 Pxl.Free;

 end;

end;

end.

Espero alguien pueda hecharme la mano con este problemilla!
Saludos..
Marck
Responder Con Cita
  #2  
Antiguo 26-12-2010
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: Sep 2004
Ubicación: En algún lugar.
Posts: 28.398
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
No conozco la respuesta a tu pregunta, sólo quería darte la bienvenida a clubdelphi
Responder Con Cita
  #3  
Antiguo 27-12-2010
Avatar de Marck Silencer
Marck Silencer Marck Silencer is offline
Registrado
 
Registrado: Dec 2010
Posts: 7
Poder: 0
Marck Silencer Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
No conozco la respuesta a tu pregunta, sólo quería darte la bienvenida a clubdelphi
Hey! Gracias por la bienvenida ! luego si te encuentras con algo que pueda ayudar te lo agradecería bastante ;D.! Saludoss
Responder Con Cita
  #4  
Antiguo 27-12-2010
Avatar de ElKurgan
[ElKurgan] ElKurgan is offline
Miembro Premium
 
Registrado: Nov 2005
Posts: 1.066
Poder: 14
ElKurgan Va por buen camino
Hola; ¿Que sistema operativo estás usando?
Al menos en mi Windows 7 (no se si en versiones anteriores) en el "administrador de tareas" viene un botón para llamar al administrador de recursos, con el que se puede visualizar como se va comiendo la memoria "privada" del programa.

Creo que estos problemas lo dan las clases Tcolor y otras, como TFont; No se muy bien porque, pero en un truco de Ian Marteens hablaba de liberar memoria que no se está usando gracias a "SetProcessWorkingSetSize".

He probado a poner en cada llamada del timer esta instrucción al iniciar el método y al cabo de un rato he obtenido estos valores en el medidor de recursos:

Mem. privada consumida por ejecutable sin liberación de memoria: 2.870 Kb
Mem. privada consumida por ejecutable CON liberación de memoria: 380 Kb

La instrucción metida al inicio del Ontimer ha sido la siguiente

Código Delphi [-]
SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);

Espero que te sirva
Un saludo
Responder Con Cita
  #5  
Antiguo 27-12-2010
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: Jul 2004
Ubicación: Barcelona - España
Posts: 15.657
Poder: 10
Neftali [Germán.Estévez] Tiene un aura espectacularNeftali [Germán.Estévez] Tiene un aura espectacular
Bienvenido al club, por mi parte también.
Por mi parte lo primero que se me ha ocurrido es evitar crear y destruir el Bitmap cada vez que accedes al Timer. Lo tienes definido fuera, así que bastaría con crearlo y destruirlo al inicio y al final. Además te evitaría tiempo de proceso innecesario.

También tengo dudas de si la llamada a Dormant debe estar justo ahí.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #6  
Antiguo 27-12-2010
Avatar de Marck Silencer
Marck Silencer Marck Silencer is offline
Registrado
 
Registrado: Dec 2010
Posts: 7
Poder: 0
Marck Silencer Va por buen camino
Thumbs up

Cita:
Empezado por ElKurgan Ver Mensaje
Hola; ¿Que sistema operativo estás usando?
Al menos en mi Windows 7 (no se si en versiones anteriores) en el "administrador de tareas" viene un botón para llamar al administrador de recursos, con el que se puede visualizar como se va comiendo la memoria "privada" del programa.

Creo que estos problemas lo dan las clases Tcolor y otras, como TFont; No se muy bien porque, hablaba de liberar memoria que no se está usando gracias a "SetProcessWorkingSetSize".

He probado a poner en cada llamada del timer esta instrucción al iniciar el método y al cabo de un rato he obtenido estos valores en el medidor de recursos:

Mem. privada consumida por ejecutable sin liberación de memoria: 2.870 Kb
Mem. privada consumida por ejecutable CON liberación de memoria: 380 Kb

La instrucción metida al inicio del Ontimer ha sido la siguiente

Código Delphi [-]
SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);

Espero que te sirva
Un saludo
Hola! Gracias por tu respuesta!..... Estoy utilizando Win XP, que buen tip, desconocia completamente esa opcion en Win Seven!, me parecee bastante buena esa opcion del SetProceesWorkingSetSize!! no la eh utilizado, ahora la pruebo a ver como se comporta ;D!!

Cita:
Empezado por Neftali Ver Mensaje
Bienvenido al club, por mi parte también.
Por mi parte lo primero que se me ha ocurrido es evitar crear y destruir el Bitmap cada vez que accedes al Timer. Lo tienes definido fuera, así que bastaría con crearlo y destruirlo al inicio y al final. Además te evitaría tiempo de proceso innecesario.

También tengo dudas de si la llamada a Dormant debe estar justo ahí.
Hola! gracias por la bienvenida!, había intentado hacer algo parecido en que sólo se creeara una vez y en el timer escanear indefinidamente utilizando ese Tbitmap creado al inicio, también me funciono pero al igual despues de un tiempo me arrojaba ese error de los recursos, entonces puse al fina del timer "Pxl.Free" y ya solo lo hacia la primer vez porque lo desrtuia, también intente intente colocar las instrucciones de ReleaseHandle ya que me marcaba algo sobre que el Tcanvas no podia dibujar y vi en el foro que tenia que liberar ese handle ya que cada vez qeu corria el timer se utilizaba otro handle pero de igual manera al liberar el handle solo lo hacia una vez....por eso no encontre otra forma más que color el create siempre en el timer si es que quería liberar los recursos pero pues ni aún asi funciona adecuadamente T-T!!

En cuanto al Dormant jaja si tienes razón esque ya despues de varias horas practicamente estaba colocando por todos lados instrucciones por la desesperación jaja xD y ese Dormant se me quedó ahi xD Saludos y gracias por tu ayuda!! Volveré tambien a intentar algo parecido a ver como me va ;D
Responder Con Cita
  #7  
Antiguo 28-12-2010
[coso] coso is offline
Miembro Premium
 
Registrado: May 2008
Ubicación: Girona
Posts: 1.677
Poder: 0
coso Va por buen camino
Hola,
el 123,123 que estas pasando a bitblt son la x e y iniciales de tu bitmap, que es de 1x1 y no llega a 123,123. Para coger el color de un unico pixel creo que no vale la pena usar un bitmap, sino accediendo directamente al monitor como ya haces, con el getdc(0). A ver si mas tarde puedo prepararte un ejemplo, aunque creo que hay alguno por aqui el club. Por otra banda, con el bitmap.free es suficiente para liberarlo (no es necesario el freeimage, etc), asi que al finalizar el ontimer queda libre, por lo que probablemente el error te venga de otro lado. saludos.

Código Delphi [-]

var
    c : TControlCanvas;
    color : TColor;
begin
    c := TcontrolCanvas.Create;

    try
           c.Handle := GetDC(0);
           color := c.Pixels[0,0];
           ...
    finally
           c.Free;
    end;
end;

quiza un poco mas sencillo...a ver si te sirve, saludos.

Última edición por coso fecha: 28-12-2010 a las 11:43:05.
Responder Con Cita
  #8  
Antiguo 28-12-2010
Avatar de Marck Silencer
Marck Silencer Marck Silencer is offline
Registrado
 
Registrado: Dec 2010
Posts: 7
Poder: 0
Marck Silencer Va por buen camino
Talking

Que tal ElKurgan, ya eh utilizado la funcion:
Código Delphi [-]
SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);
Aplicando esta función al programa hace que funcione por más tiempo eso si se notó a primera vista, pero de igual manera despues de un tiempo se va alentando (se nota al mover la ventana) y hasta que llega al limite mostrando el mismo error...x.X

Cita:
Empezado por coso Ver Mensaje
Hola,
el 123,123 que estas pasando a bitblt son la x e y iniciales de tu bitmap, que es de 1x1 y no llega a 123,123. Para coger el color de un unico pixel creo que no vale la pena usar un bitmap, sino accediendo directamente al monitor como ya haces, con el getdc(0). A ver si mas tarde puedo prepararte un ejemplo, aunque creo que hay alguno por aqui el club. Por otra banda, con el bitmap.free es suficiente para liberarlo (no es necesario el freeimage, etc), asi que al finalizar el ontimer queda libre, por lo que probablemente el error te venga de otro lado. saludos.

Código Delphi [-]

var
    c : TControlCanvas;
    color : TColor;
begin
    c := TcontrolCanvas.Create;

    try
           c.Handle := GetDC(0);
           color := c.Pixels[0,0];
           ...
    finally
           c.Free;
    end;
end;

quiza un poco mas sencillo...a ver si te sirve, saludos.
Hola!, gracias por tu respuesta!
Tienes razón en cuanto a lo del bitblt, ya probé el código que pusiste (está mejor así ) de igual manera despues de un tiempo (cabe mencionar que trabaja más tiempo que el código inicial que estaba usando) se detiene la ejecución pero ahora muestra el error de que el "Canvas no permite dibujar" algo así xD, no sé igual el problema está en estar creando y creando, y con la manipulación de los handles....

Será posible mandar llamar directamente librerias Dll de windows por ejemplo.... la "user32.dll" qeu es la qeu contiene la función GetDC y la "gdi32.dll" que contiene la función GetPixel, si la puedo mandar llamar directo me retornaría un numero entero del color, en vez de estar manejando handles, así solo sería cuestion de relizar la conversion de ese numero a el color..... Es una idea que tengo pero no se como mandar llamar funciones directamente de una DLL en Delphi. x.X

Saludos!!
Responder Con Cita
  #9  
Antiguo 29-12-2010
Avatar de Marck Silencer
Marck Silencer Marck Silencer is offline
Registrado
 
Registrado: Dec 2010
Posts: 7
Poder: 0
Marck Silencer Va por buen camino
Talking Ya lo eh conseguido!

Hey! compañeros ya ah funcionado! xD.......

Código Delphi [-]
procedure TForm1.Timer1Timer(Sender: TObject);
Var
 c : TControlCanvas;
 color : TColor;
begin
SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);
co := TcontrolCanvas.Create;
 Try
 c.Handle := GetDC(0);
 color := c.Pixels[123,123];
 panel1.Color:= color;

 finally
 deleteDC(c.Handle);
 c.Free;
 end;

end;

Utilizando el código de coso como base, utilizando la función propuesta por ElKurgan y checando más a fondo como se maneja lo del GetDC encontre que hacía falta borrar el DC obtenido al mandar llamar a la función GetDC...

Ya lo eh probado por bastante tiempo sin que se comience a alentarse y sin que me arroje algún error.....

Para escanear una área de la pantalla creen que sea conveniente utilizar un array bidimensional de Tcolor ó será mejor guardar esa área en un Bitmap?¡?
para después hacer la búsqueda del color predominante en dicha área..

Gracias por su ayuda y su tiempo..
Saludoss!!
Responder Con Cita
  #10  
Antiguo 29-12-2010
[coso] coso is offline
Miembro Premium
 
Registrado: May 2008
Ubicación: Girona
Posts: 1.677
Poder: 0
coso Va por buen camino
Hola,
el codigo que te puse no provoca error. Lo unico que ocupa memoria es el TControlCanvas, y creo que se pueden crear muchos controlcanvas en la memoria de un pc normal. El error lo debes tener por otro lado, que te esta comiendo recursos. Un saludo.

PD: Para lo que dices, creo que lo mejor seria usar bitblt copiando a un bitmap y trabajar con el. Un saludo.
Responder Con Cita
  #11  
Antiguo 29-12-2010
Avatar de Marck Silencer
Marck Silencer Marck Silencer is offline
Registrado
 
Registrado: Dec 2010
Posts: 7
Poder: 0
Marck Silencer Va por buen camino
Talking

Cita:
Empezado por coso Ver Mensaje
Hola,
el codigo que te puse no provoca error. Lo unico que ocupa memoria es el TControlCanvas, y creo que se pueden crear muchos controlcanvas en la memoria de un pc normal. El error lo debes tener por otro lado, que te esta comiendo recursos. Un saludo.

PD: Para lo que dices, creo que lo mejor seria usar bitblt copiando a un bitmap y trabajar con el. Un saludo.
OK! entonces checaré eso del Tcontrolcanvas, aunque de momento ya funcionó adecuadamente con el DeleteDC
Ok gracias por la sugerencia lo probaré con el BitBlt.....
Saludoss y gracias por tu tiempo!
Responder Con Cita
  #12  
Antiguo 27-01-2011
Avatar de sintecsl
sintecsl sintecsl is offline
Miembro
 
Registrado: Jun 2008
Ubicación: Barcelona - Spain
Posts: 40
Poder: 0
sintecsl Va por buen camino
Optimizar Memoria Mejorado

Creo que este procedimiento es mas eficaz :

Código Delphi [-]

procedure Optimizar_memoria;
var
  MainHandle : THandle;
begin
    try
     MainHandle := OpenProcess(PROCESS_ALL_ACCESS, false, GetCurrentProcessID);
     SetProcessWorkingSetSize(MainHandle,DWORD(-1),DWORD(-1));
    finally
     CloseHandle(MainHandle);
    end;
end;
__________________
www.sintecsl.es
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Liberación de un Form No Modal vejerf OOP 1 06-09-2010 19:41:20
Día mundial por la liberación de la cannabis. poliburro La Taberna 54 10-05-2008 04:55:56
Liberación de memoria de punteros Data de un Tree. afxe Varios 5 20-06-2007 17:12:34
Liberación de memoria Jome OOP 5 22-02-2007 14:44:56
Problema con tbitmap chux Gráficos 2 09-06-2006 18:11:19


La franja horaria es GMT +2. Ahora son las 00:44:03.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi