bien . Te cuento cual es la idea ...
Vemos a introducir una nueva funcion en el archivo gdiplus.cpp ...
- Code: Select all Expand view
HB_FUNC( GDIPLUSIMAGELFROMSTR )
{
void const *lpData = hb_parc(1) ;
DWORD dwSize = hb_parni(2) ;
HGLOBAL hgImage;
LPSTREAM pstm = NULL ;
HBITMAP hbmpImage;
hgImage = GlobalAlloc( GMEM_ZEROINIT | GMEM_MOVEABLE, dwSize);
char * adr = (char *)GlobalLock ( hgImage ) ;
CopyMemory( adr, lpData, dwSize);
GlobalUnlock(hgImage);
CreateStreamOnHGlobal ( hgImage, TRUE, &pstm ) ;
// CreateStreamOnHGlobal(hgImage, FALSE, &isImage );
Bitmap *original = new Bitmap( pstm,FALSE );
int nWidth = original->GetWidth() ;
int nHeight = original->GetHeight() ;
Bitmap* newImage = new Bitmap( nWidth, nHeight, original->GetPixelFormat() );
Graphics * graphics = new Graphics( newImage );
graphics->DrawImage( original ,0, 0, nWidth, nHeight);
delete graphics ;
delete original ;
GlobalFree(hgImage);
pstm->Release();
hb_retnl( ( HB_LONG ) newImage );
}
Ahora en el archivo tgdiplus.prg en la clase GDIBmp introducimos un nuevo methodo ...
- Code: Select all Expand view
METHOD LoadFromStr( cStr ) INLINE ::hBmp := GdiPlusImageLFromStr( cStr, len( cStr ) )
Tambien en tgdiplus.prg pero al final del archivo creamos una nueva funcion ....
- Code: Select all Expand view
Function oBmpLoadFromStr( oBmp, cStr, nWidth, nHeight )
local hBmpOld := oBmp:hBitmap
local hPalOld := oBmp:hPalette
local ohBmp := GDIBmp():new()
if ! Empty( cStr )
ohBmp:LoadFromStr( cStr )
if ( ! Empty( nWidth ) .or. ! Empty( nHeight ) )
ohBmp:Resize( nWidth, nHeight )
endif
oBmp:hBitmap := ohBmp:GetGDIHbitmap()
else
oBmp:hBitmap := 0
endif
oBmp:hPalette := 0
if ! Empty( hBmpOld )
PalBmpFree( hBmpOld, hPalOld )
endif
ohBmp:End()
RETURN nil
Con esto ya tenemos todo para que funcione el tema ....
Ahora un ejemplo sencillo .... usaremos un control BITMAP en vez IMAGE ....
- Code: Select all Expand view
Function Main ()
local ownd
local oimg
local cStr
//local cFile:= cGetfile("coge","*.*") // usado para probar el código
// cStr := memoread(cFile)
cStr := oEMPL:FOTO // capturamos el string de la foto
DEFINE WINDOW oWnd TITLE "Testing GDI+ Class" FROM 5,5 TO 400, 600 PIXEL ;
COLOR CLR_GRAY, CLR_GRAY
@ 20,2 button "crear" size 40,20 pixel Action imagenfromcstr( oimg , cStr )
@ 20 ,130 Button "salir" Action ownd:end() size 40,20 pixel
@ 3, 38 BITMAP oimg FILE "" size 120,120 of oWnd
ACTIVATE WINDOW oWnd
Return (nil)
Function ImagenFromcStr( obmp, cStr )
oBmpLoadFromStr( oBmp, cStr, 120, 120 )
obmp:HasAlpha()
obmp:refresh()
Return nil
Una vez cargada la imagen en el objeto bmp mediante oBmpLoadFromStr , este es un objeto bmp como cualquier otro con todos sus metodos y su comportamiento .
Dos notas al margen .
Al cargarse desde string los BMPS de 32bits son detectados como de 24 bits. por lo que no aparecen transparentes .
Podriamos convertir las imágenes de 24 bits a imágenes de 32bits y coger como canal alpha el pixel(1,1) como se hace con los Bmp "de siempre"., pero generaríamos un problema.
Como viene de un string no podemos distinguir si lo que tenemos es un bmp normal , un bmp de 32 bits o un jpg
El problema surge con las imágenes jpg por ejemplo que puede que no interese que sean transparentes , imaginad las fotos de empleados en una fichas y que la esquina sea blanca , puede que se queden sin dientes
Probado con tif ( no animados) ,gif ( no animados) , bmp, bmp32, png, y jpg .