Rotar Imagen

User avatar
leandro
Posts: 1744
Joined: Wed Oct 26, 2005 2:49 pm
Location: Colombia
Has thanked: 34 times
Been thanked: 10 times
Contact:

Rotar Imagen

Post by leandro »

Compañeros del foro buenas tardes

Lo que pasa es tengo una imagen en la pantalla la cual defino que la siguiente manera:

Code: Select all | Expand

DEFINE BRUSH oFondo FILE ".\res\res_403.BMP"
DEFINE DIALOG oDlgImg RESOURCE "ORLOTESSEG" ICON "#8001" TRANSPARENT BRUSH oFondo

  REDEFINE BUTTONBMP Btn_Canc ID 10 OF oDlgImg BITMAP "#8013" PROMPT "Cerrar" TEXTRIGHT ACTION oDlgImg:End()
  REDEFINE IMAGE oFotoEmpl ID 4001 OF oDlgImg ADJUST

  oDlgImg:cTitle := "Imagen del Lote"

ACTIVATE DIALOG oDlgImg NOWAIT CENTERED On Init (oFotoEmpl:LoadBmp( cFotoEmpl ),Centra( oDlgImg ),oDlgImg:refresh())


Image

Pero resulta que las imágenes que fueron tomadas verticalmente me las muestra al revés. Me gustaría saber si existe la posibilidad de rotarlas 90°?

Saludos
Saludos
LEANDRO AREVALO
Bogotá (Colombia)
https://hymlyma.com
https://hymplus.com/
leandroalfonso111@gmail.com
leandroalfonso111@hotmail.com

[ Turbo Incremental Link64 6.98 Embarcadero 7.70 ] [ FiveWin 24.09 ] [ xHarbour 64 bits) ]
User avatar
karinha
Posts: 7932
Joined: Tue Dec 20, 2005 7:36 pm
Location: São Paulo - Brasil
Been thanked: 3 times
Contact:

Re: Rotar Imagen

Post by karinha »

Use el editor de imagines de windows e puedes rotarlas. Grabar. Prueba. Salu2
João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
User avatar
mastintin
Posts: 1516
Joined: Thu May 27, 2010 2:06 pm

Re: Rotar Imagen

Post by mastintin »

¿ que version usas de fwh ? . En principio si usas una version reciente de fwh podrias rotarla sin problemas usando Tgdiplus y también he visto algo de código para rotar imagen sin usar tgdiplus en la nueva clase txImage.
con tgdiplus el código seria algo así ....

Code: Select all | Expand


Function dlgImagen()
local oWnd

  DEFINE WINDOW oWnd TITLE "Mostrar imagen" FROM 5,5 TO 600, 800 PIXEL
   ACTIVATE WINDOW oWn on paint DrawImage(ownd)
Return nil

function DrawImage(ownd)
local hdc:= oWnd:getdc()
local oGraphics := Graphics():New( ownd:hDC )
local oImage:= GDIBmp():new("C:\fwh\bitmaps\pngs\image2.png" )
     oImage:Rotate( 1 )
      oGraphics:DrawImage( oImage , 6 ,6, 80, 120 )
     
      oGraphics:destroy()
               
      oWnd:releasedc()

Return nil
 
User avatar
acuellar
Posts: 1645
Joined: Tue Oct 28, 2008 6:26 pm
Location: Santa Cruz-Bolivia

Re: Rotar Imagen

Post by acuellar »

Estimado Manuel

Aprovechando el post.

Es posible utilizando Tgdiplus excluir freeimage.dll extrayendo la imágen de un campo BLOB como lo hace LoadFromMemory() para poder mostrarla?

Gracias.

Saludos,

Adhemar
Saludos,

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

Re: Rotar Imagen

Post by mastintin »

acuellar wrote:Estimado Manuel

Aprovechando el post.
Es posible utilizando Tgdiplus excluir freeimage.dll extrayendo la imágen de un campo BLOB como lo hace LoadFromMemory() para poder mostrarla?
Gracias.
Saludos,
Adhemar


No lo he intentado nunca :( .
En teoria cambiando LoadFromMemory() por ImagePNGFromStr( cStr, nWidth, nHeight ) tendria que funcionar ..
la función que te pongo esta pensada para imagenes png y con ellas seguro que funciona , pero no tiene porque no funcionar con otras imagenes .
Dime el resultado y intento investigar un poco el tema ...
----------------- edito ---------------------------
Confirmado solo funciona con png :(
-------------- edito .......................
he mirado con un "apaño" y parece que funciona .....
Miralo y si funciona bien podemos intentar crear una funcion que haga lo mismo pero sin usar el archivo temporal iintermedio ....

Supongo que el blob lo grabas con cstr := memoread( "archivo.jpg")
si lo rescatas : MEMOWRIT( "imagen.txt", cStr, .f. )
luego cargas la imagen con cgi : oImage:= GDIBmp():new( "imagen.txt" )
User avatar
acuellar
Posts: 1645
Joined: Tue Oct 28, 2008 6:26 pm
Location: Santa Cruz-Bolivia

Re: Rotar Imagen

Post by acuellar »

Gracias Manuel

Tengo FWH1501 y no funciona ImagePNGFromStr()

Funciona creando un temporal y cargarlo con LoadBMP() que también necesita freeimage.dll

Code: Select all | Expand


      REDEFINE IMAGE oFoto ID 118 OF oDlg NOBORDER ADJUST
       cTemp:= hb_CurDrive() + ":\" + CurDir() + "\foto.png"    
       MEMOWRIT( cTemp, oEMPL:FOTO , .F. )
       oFoto:Loadbmp( cTemp ) //necesita freeimage.dll


Con oFoto:=GDIBmp():new( cTemp ) compila bien pero no muestra la foto.

Muchas gracias por la ayuda.

Saludos,

Adhemar
Saludos,

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

Re: Rotar Imagen

Post by mastintin »

acuellar wrote:Gracias Manuel

Tengo FWH1501 y no funciona ImagePNGFromStr()

Funciona creando un temporal y cargarlo con LoadBMP() que también necesita freeimage.dll

Code: Select all | Expand


      REDEFINE IMAGE oFoto ID 118 OF oDlg NOBORDER ADJUST
       cTemp:= hb_CurDrive() + ":\" + CurDir() + "\foto.png"    
       MEMOWRIT( cTemp, oEMPL:FOTO , .F. )
       oFoto:Loadbmp( cTemp ) //necesita freeimage.dll


Con oFoto:=GDIBmp():new( cTemp ) compila bien pero no muestra la foto.

Muchas gracias por la ayuda.

Saludos,

Adhemar


Adhemar .
¿ con el código que te he puesto ?
ten en cuenta que oImage es un objeto imagen gdi+ ....
pongo un ejemplo completo que tendria que funcionar

Code: Select all | Expand


Function dlgImagen()
local oWnd

  DEFINE WINDOW oWnd TITLE "Mostrar imagen" FROM 5,5 TO 600, 800 PIXEL
   ACTIVATE WINDOW oWn on paint DrawImage(ownd,  oEMPL:FOTO )
Return nil

function DrawImage(ownd , cStr )
local hdc:= oWnd:getdc()
local oGraphics := Graphics():New( ownd:hDC )
local oImage
local  cTemp:= hb_CurDrive() + ":\" + CurDir() + "\foto.txt"    
       MEMOWRIT( cTemp, cStr , .F. )
         oImage:= GDIBmp():new( cTemp )
     oGraphics:DrawImage( oImage , 6 ,6, 80, 120 )
     
      oGraphics:destroy()
               
      oWnd:releasedc()

Return nil


 
User avatar
acuellar
Posts: 1645
Joined: Tue Oct 28, 2008 6:26 pm
Location: Santa Cruz-Bolivia

Re: Rotar Imagen

Post by acuellar »

Funciona perfecto.

Gracias Manuel.

Como indicaste anteriormente para mejorarlo habría que evitar el temporal.

Saludos,

Adhemar
Saludos,

Adhemar C.
User avatar
acuellar
Posts: 1645
Joined: Tue Oct 28, 2008 6:26 pm
Location: Santa Cruz-Bolivia

Re: Rotar Imagen

Post by acuellar »

Estimado Manuel

Como se hace para que no se quede con la última imágen cuando el campo blob está vacío.

Funciona con oWnd:Refresh() pero hace un pestañeo toda la ventana.

Muchas gracias por la ayuda.

Saludos,

Adhemar
Saludos,

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

Re: Rotar Imagen

Post by mastintin »

bien . :D
Podemos adaptar todo para que funcione mucho mejor con código "conocido" y ya tengo creada la función que necesitamos para evitarnos el archivo temporal ... :D
La estoy probando ahora mismo y va bastante fina .
Un par de preguntas ....
1.- en tu distribucion de fwh ¿ dispones en fwh\source\winapi del archivo gdiplus.cpp ?
2.- Si lo tienes , ¿ podrias enlazar al tu programa los archivos gdiplus.cpp y tgdiplus.prg con un par de modificaciones que te pondré aqui ?
Espero tu respuesta para decirte los cambios a realizar ...
User avatar
acuellar
Posts: 1645
Joined: Tue Oct 28, 2008 6:26 pm
Location: Santa Cruz-Bolivia

Re: Rotar Imagen

Post by acuellar »

Gracias Manuel

Los tengo, son del 18/01/15

Saludos,

Adhemar
Saludos,

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

Re: Rotar Imagen

Post by mastintin »

bien . Te cuento cual es la idea ...
Vemos a introducir una nueva funcion en el archivo gdiplus.cpp ...

Code: Select all | Expand



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



 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




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




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 :D
Probado con tif ( no animados) ,gif ( no animados) , bmp, bmp32, png, y jpg .
User avatar
acuellar
Posts: 1645
Joined: Tue Oct 28, 2008 6:26 pm
Location: Santa Cruz-Bolivia

Re: Rotar Imagen

Post by acuellar »

Muchas gracias Manuel

Mañana lo pruebo y comento.

Saludos,

Adhemar
Saludos,

Adhemar C.
User avatar
acuellar
Posts: 1645
Joined: Tue Oct 28, 2008 6:26 pm
Location: Santa Cruz-Bolivia

Re: Rotar Imagen

Post by acuellar »

Estimado Manuel

Ya hice todos los cambios sugeridos, agregué los 2 programas
Compila bien, pero da este error al intentar mostrar la imagen.

Error description: Error BASE/1004 Message not found: GDIBMP:END
Args:
[ 1] = O GDIBMP

Muchas gracias.

Saludos,

Adhemar
Saludos,

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

Re: Rotar Imagen

Post by mastintin »

acuellar wrote:Estimado Manuel

Ya hice todos los cambios sugeridos, agregué los 2 programas
Compila bien, pero da este error al intentar mostrar la imagen.

Error description: Error BASE/1004 Message not found: GDIBMP:LOADFROMSTR
Args:
[ 1] = O GDIBMP

Muchas gracias.

Saludos,

Adhemar


Has añadido el metodo :

METHOD LoadFromStr( cStr ) INLINE ::hBmp := GdiPlusImageLFromStr( cStr, len( cStr ) )

en la definicion de la clase gdibmp ?
tiene toda la pinta de ser eso ....
Post Reply