Page 2 of 3

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 11:00 am
by mastintin
Creo que se donde puede venir el consumo de memoria .
Mira a ver asi :
Code: Select all  Expand view


HB_FUNC( GDIPLUSIMAGERESIZE )
{
     int nWidth =  hb_parni( 2 );
   int nHeight = hb_parni( 3 );
   Bitmap * original = ( Bitmap * ) hb_parnl( 1 );
   //Bitmap * original = new Bitmap(  (LPCWSTR) hb_parc(1)  );  
 
   Bitmap* newImage  = new Bitmap( nWidth, nHeight);
   Graphics * graphics = new Graphics( newImage );
  graphics->DrawImage( original ,0, 0, nWidth, nHeight);
  delete original ;   // nuevo
   delete graphics ; // nuevo
 hb_retnl( ( HB_LONG ) newImage );
 
}


 

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 11:18 am
by AngelSalom
Esa era la función que había aislado, correcto.
Pero aplicando los cambios que sugieres el consumo de memoria se mantiene, lo que se está quedando "en el aire" es la variable newImage
Si le arreo un delete newImage la memoria se queda perfecta pero como es lógico no me puedo cargar esa variable :( :( ... habría que encontrar el método para liberarla correctamente ya que el método Destroy de la GDIBmp no parece funcionar.

He modificado el método así :
Code: Select all  Expand view
METHOD Destroy() CLASS GDIBmp
      GlobalUnlock (::hBmp)
      GlobalFree (::hBmp)
      ::hBmp = nil
return nil


Pero nada, no se libera ...

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 11:32 am
by AngelSalom
Bueno, en el fichero CPP he modificado la función que guarda la imagen eliminado aquí newImage y la memoria de la aplicación se queda perfecta, sin desbordarse. Aquí va la pequeña modificación :

Code: Select all  Expand view
HB_FUNC( GDIPLUSIMAGESAVE )
{
  Bitmap * newImage = ( Bitmap * ) hb_parnl( 1 );
  CLSID cClsid ;
  LPWSTR file = (LPWSTR) hb_parc(2);
  LPWSTR identificador =  (LPWSTR) hb_parc(3);
  CLSIDFromString( identificador, &cClsid ) ;
   newImage->Save( file , &cClsid, NULL);
  delete newImage; // nuevo
}

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 12:49 pm
by mastintin
Angel el problema es que en muchos casos , solo queremos grabar la imagen y no "matarla" . Tendremos que hacer una nueva función "destructora" .
Colocala en el cpp
Code: Select all  Expand view


HB_FUNC( GDIPLUSIMAGEDISPOSE )
{
  Bitmap * newImage = ( Bitmap * ) hb_parnl( 1 );
   delete newImage;
}

 

En el Tgdiplus.prg , en la función después del save() coloca GDIPLUSIMAGEDISPOSE( oImage:hbmp ) y dinos como va .

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 1:58 pm
by AngelSalom
Perfecto, rápido como un tiro y sin afectar a la memoria.
La diferencia respecto a la velocidad (además de solventar el problema de los cuelgues) con freeimage es bestial :D :D
Enormemente agradecido :lol: :lol:

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 2:15 pm
by AngelSalom
5000 imágenes de diversos tamaños redimensionadas ... y subiendo, consumo de procesador ridículo y la memoria recuperada tras cada conversión ... creo que lo podemos dar por bueno, ¿no? :D :D

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 3:08 pm
by mastintin
AngelSalom wrote:5000 imágenes de diversos tamaños redimensionadas ... y subiendo, consumo de procesador ridículo y la memoria recuperada tras cada conversión ... creo que lo podemos dar por bueno, ¿no? :D :D

Yo creo que si :D .
Ayer hice los ensayos sobre una fotografia en jpg de 18mb. que presente en una exposición recientemente su ancho es de 14000px. para pasarla a 1200px . Lo hizo instantaneo y la calidad resultante me sorprendió gratamente .

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 6:42 pm
by cnavarro
Manuel, Angel, a ver si me echáis una mano
Actualmente para sacar las miniaturas de las ventanas activas en las aplicaciones que desarrollo y que aparecen en el diálogo lateral, realizo lo siguiente:

Code: Select all  Expand view

       ::oWndUI:SaveToBmp( Self:cBmpWndUI )                  //".PNG"
 


En formato .Bmp, que ocupa mucho evidentemente.
Mi pregunta: cómo puedo utilizar las rutinas que habéis desarrollado para realizar lo mismo y darle el tamaño que necesito en el diálogo lateral ?
Ando a vueltas con el tema, y espero vuestro consejo

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 8:13 pm
by mastintin
Seguro que existen muchas maneras de hacerlo .A primer pensamiento y sin análisis de la situación ,se podría en vez grabar en bmp , hacer lo siguiente :
1.- Savebmp supongo que usará un hbitmap Gdi para realizar la grabación , así que mirando el código podemos ver como conseguir ese hbitmap de la ventana , luego pasamos ese hbitmap a un objeto gdi a imagen gdi+ , partir de aquí podemos crear el tamaño y el formato de imagen que queramos y grabarlo o devolver un nuevo hbitmap gdi para usarlo en un TImage por ejemplo ...
Todo esto se me ocurre a bote pronto ...

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 8:47 pm
by cnavarro
Manuel, lo que yo hago después es cargar las imágenes generadas en un XBrowse, por si el formato a utilizar es importante
El handle a la ventana no hay problema
Pero lo demás que me explicas, es como si me hablaras en chino :shock: :shock: , y mi codigo no soporta unicode :D :D :D :P, por lo del chino lo digo :D

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 8:56 pm
by mastintin
:lol: :lol: suena a chino pero no es complicado luego ...

Lo que no entiendo muy bien es como lo usas , cuéntame porque te es problema que los bmps "pesen" algo . ¿ Cual es el proceso que usas ? , 1.- capturas la ventana en un bmp , lo grabas a disco y lo recoges para cargarlo en un xbrowse ? , es correcto ?

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 9:19 pm
by cnavarro
Has dado en el clavo
No quisiera que pesaran por si necesito hacer una version ejecutable por ejemplo desde un lapiz USB

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 9:53 pm
by mastintin
Vale Cristobal , yo creo que podemos intentarlo ...
Lo primero es mirar el código de Twindow:saveBmp() ....
Code: Select all  Expand view


METHOD SaveToBmp( cBmpFile ) CLASS TWindow

   local hBmp := WndBitmap( ::hWnd )
   local hDib := DibFromBitmap( hBmp )

   DibWrite( cBmpFile, hDib )
   GloBalFree( hDib )
   DeleteObject( hBmp )

return ( File( cBmpFile ) )

 


Creo que con la primera linea nos llega ....de aquí tenemos el hBmp ... local hBmp := WndBitmap( ::hWnd )
Te pongo un prototipo de la función a usar , faltaría comprobar los gastos de memoria y esas cosas , pero en principio sería algo así en teoría....

Code: Select all  Expand view


Function GrabaWnd( hWnd, cImageEnd, nWidtn , nHeight )

local othumb
 local hBmp := WndBitmap( hWnd )   // recogemos el hbmp
local hGDIbmp := GDIPLUSCREATEIMAGEFROMRES(  hbmp )   // creamos un puntero a la  imagen gdi+ desde el hbmp
local obmp:=GDIBmp():new()         // inicializamos la clase en vacio
        obmp:hBmp:= hGDIbmp          // y le asigmamos el puntero anterior , ya esta la clase completa.
  oThumb:=   obmp:CreateThumbnail( nWidth, nHeight )   // ahora creamos un thumbnail del tamaño que queremos
 oThumb:Save( cImageEnd )     // y grabamos la imagen  donde queramos con el formato que queramos .
  oThumb:dispose()   //liberamos memoria
  obmp:dispose()      

Return nil

 

Re: Redimensionando imágenes

PostPosted: Thu Dec 11, 2014 10:19 pm
by cnavarro
Mil gracias
Te ire contando

Re: Redimensionando imágenes

PostPosted: Fri Dec 12, 2014 9:53 am
by mastintin
Cristobal , lo tengo mas o menos funcionando , si quieres probarlo dímelo , solo tienes que enlazar un prg y un cpp a tu programa .