Redimensionando imágenes

Redimensionando imágenes

Postby AngelSalom » Wed Dec 10, 2014 9:32 am

Buenas amigos.
Estoy implementando un módulo que requiere una conversión masiva de archivos de imagen. De cada fichero saldrán 8 a distintos tamaños en una base de datos de unos 1000 registros.
Hasta la fecha he venido utilizando una función que creé aunque nunca con gran volumen de datos, sólo la llamaba en ciertos procesos de la aplicación y ningún problema. Pero ahora al procesar este volumen de imágenes el sistema queda totalmente colapsado al poco de iniciar.

Aquí el código de la función de redimensionado a ver si veis algún fallo o sugerencia. O si conocéis algún método mejor para redimensionar imágenes.
Gracias,

Code: Select all  Expand view

Function RedimensionaJPG ( cFileIn, cFileOut, nWidth, nHeight, lBorrar )
/* ===================================================================================================================
   Se ocupa de redimensionar un archivo . Se le puede pasar ancho y alto o sólo uno de los dos parámetros para
   que redimensione proporcionalmente.
   
   Parámetros : cFileIn  - Fichero de Entrada
                cFileOut - Fichero de Saluda
                nWidth   - nAncho
                nHeight  - nAlto
                lBorrar  - Borrar fichero origen
   ====================================================================================================================
*/

Local hBmp, hDib, cTempFile:=cTempFile(), lSaved
Local hResizedBitmap

  DEFAULT lBorrar:=.F.
 
  If cFileIn<>NIL .AND. cFileOut<>NIL
    // Cargo un fichero
    hBmp:=FILOADIMG (cFileIn)
   
    If hBmp<>0
      // Redimensiono hBmp
      hResizedBitmap:=RedimensionaProporcionado ( hBmp, nWidth, nHeight )

      // Guardo en fichero temporal el redimensionado
      hDib := DibFromBitmap( hResizedBitmap )
      DibWrite( cTempFile, hDib )

      // Libero memoria
      GlobalUnlock( hDib)
      GloBalFree  ( hDib )
      GlobalUnlock( hResizedBitmap )
      GlobalFree  ( hResizedBitmap )

      // Convierto un fichero en otro
      lSaved = FIConvertImageFile( cTempFile, cFileOut, 2 )

      // Borro fichero temporal
      FErase( cTempFile )

      // Borro el fichero original si es necesario
      If lSaved .AND. lBorrar
        FErase ( cFileIn )
      Endif
      SysRefresh()
    Else
        lSaved:=.F.
    Endif
  Endif

Return (lSaved)                  

Function RedimensionaProporcionado ( hbmp, nWidth, nHeight )
/* ===================================================================================================================
   Permite redimensionar un "handle" (hbmp) de forma proporcionada si se le pasa nWidth o nHeight
   
   Parámetros : hBmp   - Handle bmp creado
                nWidth - Ancho
                nHeight  - nAlto
 
   ====================================================================================================================
*/


Local hResizedBitmap:=hBmp

  If Valtype( nWidth ) == "N" .AND. Valtype( nHeight ) == "N"
    If nBmpWidth( hBmp )>nWidth .OR. nBmpHeight( hBmp )>nHeight
      hResizedBitmap := ResizeBmp( hBmp, nWidth, nHeight )
    Endif
 
  ElseIf Valtype( nWidth ) == "N"
     If nBmpWidth( hBmp ) > nWidth
       hResizedBitmap := ResizeBmp( hBmp, nWidth, nBmpHeight( hBmp ) / ( nBmpWidth( hBmp ) /nWidth ) )
     Endif
  ElseIf Valtype( nHeight )=="N"
     If nBmpHeight( hBmp ) > nHeight
        hResizedBitmap := ResizeBmp( hBmp, nBmpWidth( hBmp ) / (nBmpHeight( hBmp ) / nHeight ), nHeight )
     Endif
  Endif
Return (hResizedBitmap)  

 
Angel Salom
Visionwin Software - https://www.visionwin.com
------------------------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.4
User avatar
AngelSalom
 
Posts: 708
Joined: Fri Oct 07, 2005 7:38 am
Location: Benicarló (Castellón ) - España

Re: Redimensionando imágenes

Postby mastintin » Wed Dec 10, 2014 10:32 am

Aqui usas la libreria freeimage para hacer las conversiones , estos dias atras hemos creado un codigo que usa gdi+ para hacerlo ....
Si te interesa intentarlo sería estupendo para comprobar que efectivamante funciona bien .
Tendrias que crear un archivo cpp con un codigo y enlazarlo y tambien una pequeña función .
Saludos.
User avatar
mastintin
 
Posts: 1516
Joined: Thu May 27, 2010 2:06 pm

Re: Redimensionando imágenes

Postby AngelSalom » Wed Dec 10, 2014 10:48 am

Mastitin, Si me indicas cómo me tiro de cabeza :D :D
Angel Salom
Visionwin Software - https://www.visionwin.com
------------------------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.4
User avatar
AngelSalom
 
Posts: 708
Joined: Fri Oct 07, 2005 7:38 am
Location: Benicarló (Castellón ) - España

Re: Redimensionando imágenes

Postby mastintin » Wed Dec 10, 2014 11:26 am

pues vamos a ello :
Crea un nuevo archivo gdiplusfun.cpp y coloca dentro :
Code: Select all  Expand view


#include <hbapi.h>
#include <windows.h>
#include <gdiplus.h>

using namespace Gdiplus;

GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR   gdiplusToken;



HB_FUNC( GDIPLUSCREATEIMAGEFROMFILE )
{
    Bitmap * newImage =  new Bitmap(  (LPCWSTR) hb_parc(1)  );  
  hb_retnl( ( HB_LONG ) newImage );
 
}

//----------------------------------------------------------------------------//

HB_FUNC( GDIPLUSGETWIDTHBITMAP)
{
  Bitmap * newImage = ( Bitmap * ) hb_parnl( 1 );
  hb_retnl( ( HB_LONG )   newImage->GetWidth() );
}

//----------------------------------------------------------------------------//

HB_FUNC( GDIPLUSGETHEIGHTBITMAP)
{
  Bitmap * newImage = ( Bitmap * ) hb_parnl( 1 );
  hb_retnl( ( HB_LONG ) newImage->GetHeight() );
}

//----------------------------------------------------------------------------//

HB_FUNC( GDIPLUSCREATETHUMBNAILIMAGE )
{
  Bitmap * newImage = ( Bitmap * ) hb_parnl( 1 );
  int nWidth  = hb_parnd( 2 );
  int nHeight = hb_parnd( 3 );
   
  Image * thumb = newImage->GetThumbnailImage( nWidth, nHeight, NULL, NULL  ) ;
   
  hb_retnl( ( HB_LONG ) thumb );
 
}


HB_FUNC( GDIPLUSIMAGESAVE )
{
  Image * newImage = ( Image * ) 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);
}


 



en cualquiera de tus prg coloca esta funcion :

Code: Select all  Expand view

Function GDIPlusSaveThumbnail( cImageIni, cImageEnd , nWidth, nHeight )

local cExtIni := Upper(cFileExt( cImageIni ))
local cExtEnd := Upper(cFileExt(cImageEnd ))
local hImage:= GDIPLUSCREATEIMAGEFROMFILE( cImageIni )
local hThumb
local nScan
local nRatio
local nOldWidth  := GDIPLUSGETWIDTHBITMAP( hImage )
local nOldHeight := GDIPLUSGETHEIGHTBITMAP( hImage )
local aExtIni := { "BMP", "JPG", "GIF", "TIF", "PNG" }
local aExtEnd := { "BMP", "JPG", "GIF", "TIF", "PNG" }
local aCLSID  := { "{557CF400-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF401-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF402-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF405-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF406-1A04-11D3-9A73-0000F81EF32E}"  ;
               }

local cCLSID

  if Empty( nHeight )
     nRatio := nOldWidth / nOldHeight
     nHeight := nWidth * nRatio
  endif

 if( nScan:= aScan( aExtIni, cExtIni )) == 0
    Msginfo( " el archivo "+ cImageIni + " tiene un formato no soportado")
    return .f.
 endif

 hThumb:= GDIPLUSCREATETHUMBNAILIMAGE( hImage, nWhidth, nHeight )
 
 nScan:= aScan( aExtEnd, cExtend )

 if nScan == 0
    msginfo( "Formato no soportado" )
    Return .f.
endif

 cCLSID := aCLSID[ nScan ]
 
 cCLSID = AnsiToWide( cCLSID )
 cImageEnd  = AnsiToWide( cImageEnd )

 GdiPlusImageSave( hThumb, cImageEnd, cCLSID )
 
 
 
hImage:= nil
hThumb:= nil

return .t.

 


enlaza el nuevo archivo y listo .
Dime si he metido algun gazapo o te da algún error...
Last edited by mastintin on Wed Dec 10, 2014 2:23 pm, edited 1 time in total.
User avatar
mastintin
 
Posts: 1516
Joined: Thu May 27, 2010 2:06 pm

Re: Redimensionando imágenes

Postby Antonio Linares » Wed Dec 10, 2014 11:30 am

+1 ;-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41318
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Redimensionando imágenes

Postby AngelSalom » Wed Dec 10, 2014 2:37 pm

Bueno, me he puesto a ello pero sin éxito de momento.

He montado un ejemplo autocontenido antes de implantarlo en la aplicación. El gdiplusfan.cpp es tal cual me lo pasa mastitin, pero lo copio también aquí. La función GDIPLusSaveThumbnail tiene un pequeño cambio para poner algún msginfo que vaya desvelando los problemas. Bien, el tema es que GDIPLUSCREATEIMAGEFROMFILE devuelve 0 y al llamar a GDIPLUSGETWIDTHBITMAP con el handle el programa revienta con el fallo de windows "test.exe dejó de funcionar ...".

Dejo también el fichero de compilado a ver si hago algo mal.
Saludetes,

test.prg
Code: Select all  Expand view

#include "fivewin.ch"

Function Main ()

  GDIPlusSaveThumbnail ("c:\envio\captura.jpg", "c:\envio\captura2.jpg",100 )
 
Return (nil)

Function GDIPlusSaveThumbnail( cImageIni, cImageEnd , nWidth, nHeight )

local cExtIni := Upper(cFileExt( cImageIni ))
local cExtEnd := Upper(cFileExt(cImageEnd ))
local hImage
local hThumb
local nScan
local nRatio
local nOldWidth  
local nOldHeight
local aExtIni := { "BMP", "JPG", "GIF", "TIF", "PNG" }
local aExtEnd := { "BMP", "JPG", "GIF", "TIF", "PNG" }
local aCLSID  := { "{557CF400-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF401-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF402-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF405-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF406-1A04-11D3-9A73-0000F81EF32E}"  ;
               }

local cCLSID
 
  msginfo (file (cimageini) )
 
  hImage:=GDIPLUSCREATEIMAGEFROMFILE( cImageIni )
  msginfo (himage)

  nOldWidth  := GDIPLUSGETWIDTHBITMAP( hImage )
  msginfo (nOldWidth)

  nOldHeight := GDIPLUSGETHEIGHTBITMAP( hImage )
  msginfo (nOldHeight)

  DEFAULT nWidth:=nOldWidth
 

  if Empty( nHeight )
     nRatio := nOldWidth / nOldHeight
     nHeight := nWidth * nRatio
  endif

 if( nScan:= aScan( aExtIni, cExtIni )) == 0
    Msginfo( " el archivo "+ cImageIni + " tiene un formato no soportado")
    return .f.
 endif

 hThumb:= GDIPLUSCREATETHUMBNAILIMAGE( hImage, nWhidth, nHeight )
 
 nScan:= aScan( aExtEnd, cExtension )

 if nScan == 0
    msginfo( "Formato no soportado" )
    Return .f.
endif

 cCLSID := aCLSID[ nScan ]
 
 cCLSID = AnsiToWide( cCLSID )
 cImageEnd  = AnsiToWide( cImageEnd )

 GdiPlusImageSave( hThumb, cImageEnd, cCLSID )
 
 
 
hImage:= nil
hThumb:= nil

return .t.

 


gdiplusfan.cpp
Code: Select all  Expand view


#include <hbapi.h>
#include <windows.h>
#include <gdiplus.h>

using namespace Gdiplus;

GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR   gdiplusToken;



HB_FUNC( GDIPLUSCREATEIMAGEFROMFILE )
{
    Bitmap * newImage =  new Bitmap(  (LPCWSTR) hb_parc(1)  );  
  hb_retnl( ( HB_LONG ) newImage );
 
}

//----------------------------------------------------------------------------//

HB_FUNC( GDIPLUSGETWIDTHBITMAP)
{
  Bitmap * newImage = ( Bitmap * ) hb_parnl( 1 );
  hb_retnl( ( HB_LONG )   newImage->GetWidth() );
}

//----------------------------------------------------------------------------//

HB_FUNC( GDIPLUSGETHEIGHTBITMAP)
{
  Bitmap * newImage = ( Bitmap * ) hb_parnl( 1 );
  hb_retnl( ( HB_LONG ) newImage->GetHeight() );
}

//----------------------------------------------------------------------------//

HB_FUNC( GDIPLUSCREATETHUMBNAILIMAGE )
{
  Bitmap * newImage = ( Bitmap * ) hb_parnl( 1 );
  int nWidth  = hb_parnd( 2 );
  int nHeight = hb_parnd( 3 );
   
  Image * thumb = newImage->GetThumbnailImage( nWidth, nHeight, NULL, NULL  ) ;
   
  hb_retnl( ( HB_LONG ) thumb );
 
}


HB_FUNC( GDIPLUSIMAGESAVE )
{
  Image * newImage = ( Image * ) 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);
}


 
 


c.bat
Code: Select all  Expand view

@ECHO OFF

set hdir  = c:\SI\NLEN\harbour
set bcdir = c:\SI\NLEN\bcc582
set fwdir = c:\si\nlen\fwh1204

%bcdir%\bin\bcc32 -M -c -v -O2 -I%hdir%\include;%bcdir%\include;%bcdir%\include\dinkumware gdiplusfan.cpp
%hdir%\bin\harbour test.prg /i%fwdir%\include;%hdir%\include;%bcdir%\include
%bcdir%\bin\bcc32 -M -c -I%hdir%\include;%bcdir%\include %test.c

echo %bcdir%\lib\c0w32.obj + > b32.bc
echo test.obj        +>> b32.bc
echo gdiplusfan.obj, +>> b32.bc
echo test.exe,       + >> b32.bc
echo test.map,       + >> b32.bc

echo %fwdir%\lib\FiveH.lib %fwdir%\lib\FiveHC.lib + >> b32.bc
echo %hdirl%\hbrtl.lib + >> b32.bc
echo %hdirl%\hbvm.lib + >> b32.bc
echo %hdirl%\gtgui.lib + >> b32.bc
echo %hdirl%\hblang.lib + >> b32.bc
echo %hdirl%\hbmacro.lib + >> b32.bc
echo %hdirl%\hbrdd.lib + >> b32.bc
echo %hdirl%\rddntx.lib + >> b32.bc
echo %hdirl%\rddcdx.lib + >> b32.bc
echo %hdirl%\rddfpt.lib + >> b32.bc
echo %hdirl%\hbsix.lib + >> b32.bc
echo %hdirl%\hbdebug.lib + >> b32.bc
echo %hdirl%\hbcommon.lib + >> b32.bc
echo %hdirl%\hbpp.lib + >> b32.bc
echo %hdirl%\hbcpage.lib + >> b32.bc
echo %hdirl%\hbwin.lib + >> b32.bc
echo %hdirl%\hbcplr.lib + >> b32.bc
echo %hdirl%\hbct.lib + >> b32.bc
echo %hdirl%\hbpcre.lib + >> b32.bc
echo %hdirl%\xhb.lib + >> b32.bc
echo %hdirl%\hbziparc.lib + >> b32.bc
echo %hdirl%\hbmzip.lib + >> b32.bc
echo %hdirl%\hbzlib.lib + >> b32.bc
echo %hdirl%\minizip.lib + >> b32.bc
echo %hdirl%\png.lib + >> b32.bc

echo %bcdir%\lib\cw32.lib + >> b32.bc
echo %bcdir%\lib\uuid.lib + >> b32.bc
echo %bcdir%\lib\import32.lib + >> b32.bc
echo %bcdir%\lib\ws2_32.lib + >> b32.bc
echo %bcdir%\lib\psdk\odbc32.lib + >> b32.bc
echo %bcdir%\lib\psdk\nddeapi.lib + >> b32.bc
echo %bcdir%\lib\psdk\iphlpapi.lib + >> b32.bc
echo %bcdir%\lib\psdk\msimg32.lib + >> b32.bc
echo %bcdir%\lib\psdk\psapi.lib + >> b32.bc
echo %bcdir%\lib\psdk\rasapi32.lib + >> b32.bc
echo %bcdir%\lib\psdk\gdiplus.lib + >> b32.bc
echo %bcdir%\lib\psdk\shell32.lib, + >> b32.bc

%bcdir%\bin\ilink32 -Gn -aa -Tpe -s @b32.bc


 
Angel Salom
Visionwin Software - https://www.visionwin.com
------------------------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.4
User avatar
AngelSalom
 
Posts: 708
Joined: Fri Oct 07, 2005 7:38 am
Location: Benicarló (Castellón ) - España

Re: Redimensionando imágenes

Postby mastintin » Wed Dec 10, 2014 5:54 pm

Bien en el prg :
Dos gazapos ...

hThumb:= GDIPLUSCREATETHUMBNAILIMAGE( hImage, nWidth, nHeight ) // bug
nScan:= aScan( aExtEnd, cExtend ) // bug

y añadir :



init procedure GdiPlusStart()

GdiPlusStartup()

return

//----------------------------------------------------------------------------//

exit procedure GdiPlusEnd()

GdiPlusShutdown()

return

en el cpp :
añadir :


HB_FUNC( GDIPLUSSTARTUP )
{
hb_retl( GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, NULL ) );
}

//----------------------------------------------------------------------------//

HB_FUNC( GDIPLUSSHUTDOWN )
{
GdiplusShutdown( gdiplusToken );
}

Sigo buscando los gazapos.... ahora no nos devuelve el ancho y el alto
User avatar
mastintin
 
Posts: 1516
Joined: Thu May 27, 2010 2:06 pm

Re: Redimensionando imágenes

Postby AngelSalom » Wed Dec 10, 2014 7:04 pm

Aplicados los cambios que sugieres mastintin, ahora no da el fallo y ciertamente devuelve el ancho y alto a cero ... he probado a pasarle valores tanto de ancho como de alto para que no tenga que calcular y la función GDIPLUSCREATETHUMBNAILIMAGE parece que devuelve un handle correcto, en cambio la GdiPlusImageSave parece no hacer nada.
He comprobado las cadenas cCLSID y cImageEnd y parece que contienen la información adecuada ...
:shock: :shock:
Angel Salom
Visionwin Software - https://www.visionwin.com
------------------------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.4
User avatar
AngelSalom
 
Posts: 708
Joined: Fri Oct 07, 2005 7:38 am
Location: Benicarló (Castellón ) - España

Re: Redimensionando imágenes

Postby mastintin » Wed Dec 10, 2014 7:18 pm

Una pregunta . ¿Tienes en tu fwh Tgdiplus.prg ? c:\fwh\source\clases
User avatar
mastintin
 
Posts: 1516
Joined: Thu May 27, 2010 2:06 pm

Re: Redimensionando imágenes

Postby AngelSalom » Wed Dec 10, 2014 8:03 pm

Si, aquí te pego el contenido. La versión de FWH que uso es de Abril del 2012. Tengo también la versión de febrero de 2014 pero es la de 64bits, pendiente de migrar las aplicaciones :oops:

Code: Select all  Expand view

// GdiPlus support classes. (c) FiveTech Software 2011

#include "FiveWin.ch"

#DEFINE GDI_PEN_ROUND   1

//----------------------------------------------------------------------------//

CLASS Graphics

   DATA   hGraphics

   METHOD New( hDC , lNoHighQuality )

   METHOD SetHighQuality( ) INLINE GdiPlusHighQuality( ::hGraphics )

   METHOD SetNormalQuality( ) INLINE GdiPlusNormalQuality( ::hGraphics )

   METHOD DrawLine( oPen, nLeft, nTop, nRight, nBottom ) INLINE ;
          GdiPlusDrawLine( ::hGraphics, if(!empty(oPen),oPen:hPen,NIL), nLeft, nTop, nRight, nBottom )

   METHOD DrawRect( oPen, oBrush, nLeft, nTop, nWidth, nHight ) INLINE ;
          GdiPlusDrawRect( ::hGraphics, if(!empty(oPen),oPen:hPen,NIL), if(!empty(oBrush),oBrush:hBrush,NIL) , nLeft, nTop, nWidth, nHight )

   METHOD DrawEllipse( oPen, oBrush, nLeft, nTop, nWidth, nHight ) INLINE ;
          GdiPlusDrawEllipse( ::hGraphics, if(!empty(oPen),oPen:hPen,NIL), if(!empty(oBrush),oBrush:hBrush,NIL) , nLeft, nTop, nWidth, nHight )

   METHOD Destroy()

   DESTRUCTOR Destroy()

ENDCLASS

//----------------------------------------------------------------------------//

METHOD New( hDC , lNoHighQuality ) CLASS Graphics

   ::hGraphics = GdiPlusNewGraphics( hDC )

   DEFAULT lNoHighQuality := .F.

   if lNoHighQuality
    ::SetNormalQuality( )
   else
    ::SetHighQuality( )
   endif

return Self

//----------------------------------------------------------------------------//

METHOD Destroy() CLASS Graphics

   GdiPlusDeleteGraphics( ::hGraphics )

   ::hGraphics = nil

return nil

//----------------------------------------------------------------------------//

CLASS Pen

   DATA   hPen

   METHOD New( nTrans, nRed, nGreen, nBlue, nSize, lRound, lAlign )

   METHOD SetSize( nSize ) INLINE GdiPlusPenSize( ::hPen , nSize )

   METHOD SetStyle( nStyle )

   METHOD SetInset( ) INLINE GdiPlusAlign( ::hPen )

   METHOD SetNoInset( ) INLINE GdiPlusNoAlign( ::hPen )

   METHOD Destroy()

   DESTRUCTOR Destroy()

ENDCLASS

//----------------------------------------------------------------------------//

METHOD New( nTrans, nRed, nGreen, nBlue, nSize, lRound, lAlign ) CLASS Pen

   ::hPen = GdiPlusNewPen( nTrans, nRed, nGreen, nBlue )

   DEFAULT nSize := 1 , lRound := .F. , lAlign := .F.

   ::SetSize( nSize )

   if lRound
        ::SetStyle ( GDI_PEN_ROUND )
     endif
   
     if lAlign
          ::SetAlign ( )
     endif

return Self

//----------------------------------------------------------------------------//

METHOD SetStyle( nStyle ) CLASS Pen

   do case
        case nStyle == GDI_PEN_ROUND
               GdiPlusPenStyle( ::hPen, 2 )

   endcase

return nil

//----------------------------------------------------------------------------//

METHOD Destroy() CLASS Pen

   GdiPlusDeletePen( ::hPen )

   ::hPen = nil

return nil

//----------------------------------------------------------------------------//

CLASS Brush

   DATA   hBrush

   METHOD NewSolidBrush( nTrans, nRed, nGreen, nBlue )

   METHOD Destroy()

   DESTRUCTOR Destroy()

ENDCLASS

//----------------------------------------------------------------------------//

METHOD NewSolidBrush( nTrans, nRed, nGreen, nBlue ) CLASS Brush

   ::hBrush = GdiPlusNewSolidBrush( nTrans, nRed, nGreen, nBlue )

return Self

//----------------------------------------------------------------------------//

METHOD Destroy() CLASS Brush

   GdiPlusDeleteBrush( ::hBrush )

   ::hBrush = nil

return nil

//----------------------------------------------------------------------------//

init procedure GdiPlusStart()

   GdiPlusStartup()

return

//----------------------------------------------------------------------------//

exit procedure GdiPlusEnd()

   GdiPlusShutdown()

return

//----------------------------------------------------------------------------//
 
Angel Salom
Visionwin Software - https://www.visionwin.com
------------------------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.4
User avatar
AngelSalom
 
Posts: 708
Joined: Fri Oct 07, 2005 7:38 am
Location: Benicarló (Castellón ) - España

Re: Redimensionando imágenes

Postby mastintin » Wed Dec 10, 2014 11:05 pm

Ya lo tengo funcionando . He recreado los archivos que copio y parece funcionar bien . Espero no falte nada que este cogiendo de las librerías fwh y que tu no tengas .
Bien . Vamos a hacerlo de otra forma . Vamos a copiar el archivo tgdiplus.prg al directorio donde estés trabajando el ejemplo y lo añadimos al bat .
Ahora al final del archivo añadimos la clase bitmap .

Code: Select all  Expand view


CLASS GDIBmp

   DATA hBmp
   DATA aCLSID
   DATa aExtIni, aExtEnd
   
   METHOD New( cFile )
   METHOD Destroy()
   METHOD Save( cFile )
   METHOD getwidth() INLINE GDIPLUSGETWIDTHBITMAP( ::hBmp )  
   METHOD getHeight() INLINE GDIPLUSGETHEIGHTBITMAP( ::hBmp )  
   DESTRUCTOR Destroy()

ENDCLASS


//----------------------------------------------------------------------------//

METHOD New( cFile ) CLASS GDIBmp
local aBmpPal

 
   ::aExtIni := { "BMP", "JPG", "GIF", "TIF", "PNG","EMF","WMF","ICO" }
   ::aExtEnd := { "BMP", "JPG", "GIF", "TIF", "PNG" }
   ::aCLSID := { "{557CF400-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF401-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF402-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF405-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF406-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF403-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF404-1A04-11D3-9A73-0000F81EF32E}" ,;
                               "{557CF407-1A04-11D3-9A73-0000F81EF32E}" ;
               }
     
   
  if !Empty(cFile)
      if File( cFile )
       ::hBmp = GdiPlusCreateImageFromFile( AnsiToWide( cFile ) )  
      else
        msginfo( "fichero no encontrados" )    
      endif  
   endif
                       
return Self


//----------------------------------------------------------------------------//

METHOD Save( cFile ) CLASS GDIBmp
local cExtension := Upper(cFileExt(cFile))
local cCLSID

local nScan:= aScan( ::aExtEnd, cExtension )

if nScan == 0
    msginfo( "Formato no soportado" )
    Return .f.
endif

 cCLSID := ::aCLSID[ nScan ]
 
 cCLSID = AnsiToWide( cCLSID )
 cFile  = AnsiToWide( cFile )
 
 GdiPlusImageSave( ::hBmp, cFile, cCLSID )

Return nil


METHOD Destroy() CLASS GDIBmp
      ::hBmp = nil
return nil


Function GDIPlusResizeImage( cImageIni, cImageEnd , nWidth, nHeight )

local cExtIni := Upper(cFileExt( cImageIni ))
local cExtEnd := Upper(cFileExt( cImageEnd ))
local oImage
local nScan
local nOldHeight, nOldWidth, nRatio

if cImageIni == cImageEnd
   msginfo( "Error. La imagen inicial y final son la misma" )
   Return .f.
endif


oImage:= GDIBmp():New( cImageIni )

 if( nScan:= aScan( oImage:aExtIni, cExtIni )) == 0
    Msginfo( " el archivo "+ cImageIni + " tiene un formato no soportado")
    return .f.
 endif
 
 if( nScan:= aScan( oImage:aExtEnd, cExtEnd )) == 0
    Msginfo( " el archivo "+ cImageEnd + " tiene un formato no soportado")
    return .f.
 endif
 
 
  nOldWidth  := oImage:getWidth()
  nOldHeight := oImage:GetHeight()
   
 if Empty( nHeight )
     nRatio :=  nOldHeight / nOldWidth
     nHeight := nWidth * nRatio
  endif
 
   if Empty( nWidth )
     nRatio :=  nOldHeight /  nOldWidth
     nWidth := nHeight * nRatio
  endif


 
oImage:hBmp:= GDIPLUSIMAGERESIZE(oImage:hBmp ,  nWidth, nHeight )
 
oImage:Save( cImageEnd )
oImage:Destroy()

Return nil



 


ahora vamos con el archivo cpp . Borra lo que tengas en el y vamos a poner lo que copio aquí :

Code: Select all  Expand view


// GdiPlus support (c) FiveTech Software

#include <hbapi.h>
#include <windows.h>
#include <gdiplus.h>



using namespace Gdiplus;

GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR   gdiplusToken;


//----------------------------------------------------------------------------//

HB_FUNC( GDIPLUSGETWIDTHBITMAP)
{
  Bitmap * newImage = ( Bitmap * ) hb_parnl( 1 );
  hb_retnl( ( HB_LONG )   newImage->GetWidth() );
}

//----------------------------------------------------------------------------//

HB_FUNC( GDIPLUSGETHEIGHTBITMAP)
{
  Bitmap * newImage = ( Bitmap * ) hb_parnl( 1 );
  hb_retnl( ( HB_LONG ) newImage->GetHeight() );
}

//----------------------------------------------------------------------------//

//----------------------------------------------------------------------------//

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);

 hb_retnl( ( HB_LONG ) newImage );
 
}

//----------------------------------------------------------------------------//

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);
   
}

HB_FUNC( GDIPLUSCREATEIMAGEFROMFILE )
{
    Bitmap * newImage =  new Bitmap(  (LPCWSTR) hb_parc(1)  );  
  hb_retnl( ( HB_LONG ) newImage );
 
}



 


Por ultimo el test, esto falta colocarlo bonito : :D .

Code: Select all  Expand view


#include "FiveWin.ch"

Function Main ()
local ownd

 DEFINE WINDOW oWnd TITLE "Testing GDI+ Class" FROM 5,5 TO 600, 800 PIXEL
   
       @ 2,2 button "crear" Action  ( GDIPlusResizeImage( "c:\fwh\bitmaps\pngs\image13.png" , "c:\fwh\bitmaps\pngs\image13333.png" , 50  ) )
   
    @ 2 ,30 Button "salir" Action ownd:end()
     
    ACTIVATE WINDOW oWnd


Return (nil)

 


Espero que no mwe falte nada ....
User avatar
mastintin
 
Posts: 1516
Joined: Thu May 27, 2010 2:06 pm

Re: Redimensionando imágenes

Postby AngelSalom » Thu Dec 11, 2014 8:03 am

Bueeeeeeno. Ahora SI que ha funcionado.
Voy a adaptarlo a la aplicación, haré el test de conversión "masivo" y os cuento los resultados.
:D :D
Angel Salom
Visionwin Software - https://www.visionwin.com
------------------------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.4
User avatar
AngelSalom
 
Posts: 708
Joined: Fri Oct 07, 2005 7:38 am
Location: Benicarló (Castellón ) - España

Re: Redimensionando imágenes

Postby Antonio Linares » Thu Dec 11, 2014 8:26 am

Manuel y Angel,

Muchas gracias, esto es muy bueno para todos :-)

Manuel, hay algún cambio que incluir nuevo a FWH ?

gracias!!!
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41318
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Redimensionando imágenes

Postby mastintin » Thu Dec 11, 2014 10:30 am

Antonio , Vamos a esperar los resultados de Angel , pero en principio si que tenemos cosas para incluir ...

en cpp 3 funciones :

Code: Select all  Expand view


//----------------------------------------------------------------------------//

HB_FUNC( GDIPLUSGETWIDTHBITMAP)
{
  Bitmap * newImage = ( Bitmap * ) hb_parnl( 1 );
  hb_retnl( ( HB_LONG )   newImage->GetWidth() );
}

//----------------------------------------------------------------------------//

HB_FUNC( GDIPLUSGETHEIGHTBITMAP)
{
  Bitmap * newImage = ( Bitmap * ) hb_parnl( 1 );
  hb_retnl( ( HB_LONG ) newImage->GetHeight() );
}

//----------------------------------------------------------------------------//

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);

 hb_retnl( ( HB_LONG ) newImage );
 
}


 


en el tgdiimage.prg :
3 metodos y una funcion :

Code: Select all  Expand view

  CLASS GDIBmp
  ....
  METHOD getwidth() INLINE GDIPLUSGETWIDTHBITMAP( ::hBmp )  
  METHOD getHeight() INLINE GDIPLUSGETHEIGHTBITMAP( ::hBmp )  
 ....


Function GDIPlusResizeImage( cImageIni, cImageEnd , nWidth, nHeight )

local cExtIni := Upper(cFileExt( cImageIni ))
local cExtEnd := Upper(cFileExt( cImageEnd ))
local oImage
local nScan
local nOldHeight, nOldWidth, nRatio

if cImageIni == cImageEnd
   msginfo( "Error. La imagen inicial y final son la misma" )
   Return .f.
endif


oImage:= GDIBmp():New( cImageIni )

 if( nScan:= aScan( oImage:aExtIni, cExtIni )) == 0
    Msginfo( " el archivo "+ cImageIni + " tiene un formato no soportado")
    return .f.
 endif
 
 if( nScan:= aScan( oImage:aExtEnd, cExtEnd )) == 0
    Msginfo( " el archivo "+ cImageEnd + " tiene un formato no soportado")
    return .f.
 endif
 
 
  nOldWidth  := oImage:getWidth()
  nOldHeight := oImage:GetHeight()
   
 if Empty( nHeight )
     nRatio :=  nOldHeight / nOldWidth
     nHeight := nWidth * nRatio
  endif
 
   if Empty( nWidth )
     nRatio :=  nOldHeight /  nOldWidth
     nWidth := nHeight * nRatio
  endif


 
oImage:hBmp:= GDIPLUSIMAGERESIZE(oImage:hBmp ,  nWidth, nHeight )
 
oImage:Save( cImageEnd )
oImage:Destroy()

Return nil


 

queda un nuevo methodo resize() pendiente de probar ...
su codigo :
Code: Select all  Expand view


METHOD Resize( nWidth, nHeight ) CLASS GDIBmp
local nRatio
local nOldWidth  := ::getWidth()
local nOldHeight := ::GetHeight()
   
 if Empty( nHeight )
     nRatio :=  nOldHeight / nOldWidth
     nHeight := nWidth * nRatio
  endif
 
   if Empty( nWidth )
     nRatio :=  nOldHeight /  nOldWidth
     nWidth := nHeight * nRatio
  endif
 
  ::hBmp:= GdiPlusImageResize(::hBmp , nWidth, nHeight )

 
User avatar
mastintin
 
Posts: 1516
Joined: Thu May 27, 2010 2:06 pm

Re: Redimensionando imágenes

Postby AngelSalom » Thu Dec 11, 2014 10:53 am

Os cuento. Acabo de hacer un test a lo bruto en un bucle redimensionando 5000 imágenes y ha funcionado rápido, muy rápido.
Peeeeero (siempre hay un pero), el consumo de memoria se incrementa en cada conversión provocando en el tiempo un "Cannot allocate memory" , estoy intentando aislar la parte de la conversión que se come la memoria ... ya os cuento.
Angel Salom
Visionwin Software - https://www.visionwin.com
------------------------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.4
User avatar
AngelSalom
 
Posts: 708
Joined: Fri Oct 07, 2005 7:38 am
Location: Benicarló (Castellón ) - España

Next

Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 9 guests