Ir al contenido


Foto

[MULTILENGUAJE] FlipImage


  • Por favor identifícate para responder
2 respuestas en este tema

#1 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.965 mensajes
  • LocationMadrid - España

Escrito 08 marzo 2012 - 05:27

Otra vez con el GDIpus a cuestas...

En ocasiones interesa rotar una imagen en incrementos de 90º, otras veces queremos invertirla (180º) o conseguir una imagen especular.

El código que presento realiza ésto de forma muy simple y con GDI plus. Podremos rotar fácil y eficientemente una imagen en múltiplos de 90 grados y combinar esa rotación con un flp especular.

Como siempre voy a escribir el ejemplo en C/C++ y delphi:
 


cpp
  1. #pragma link "Gdiplus.lib" // poner la ruta dentro de las libreriras
  2.  
  3. extern "C" {
  4. DWORD WINAPI GdiplusStartup(ULONG_PTR *hToken, void *input, void *Output);
  5. void  WINAPI GdiplusShutdown(ULONG_PTR token);
  6. DWORD WINAPI GdipCreateBitmapFromHBITMAP(HBITMAP hBmp, HPALETTE hPal, HANDLE* GBitmap);
  7. DWORD WINAPI GdipCreateHBITMAPFromBitmap(HANDLE Bmp, HBITMAP* hBmp, DWORD BKColor);
  8. DWORD WINAPI GdipDisposeImage(HANDLE hImage);
  9. DWORD WINAPI GdipImageRotateFlip(HANDLE hImage, DWORD rfType);
  10. }
  11.  
  12. typedef enum  {
  13.   RotateNoneFlipNone  = 0,
  14.   Rotate90FlipNone    = 1,
  15.   Rotate180FlipNone    = 2,
  16.   Rotate270FlipNone    = 3,
  17.   RotateNoneFlipX      = 4,
  18.   Rotate90FlipX        = 5,
  19.   Rotate180FlipX      = 6,
  20.   Rotate270FlipX      = 7,
  21.   RotateNoneFlipY      = Rotate180FlipX,
  22.   Rotate90FlipY        = Rotate270FlipX,
  23.   Rotate180FlipY      = RotateNoneFlipX,
  24.   Rotate270FlipY      = Rotate90FlipX,
  25.   RotateNoneFlipXY    = Rotate180FlipNone,
  26.   Rotate90FlipXY      = Rotate270FlipNone,
  27.   Rotate180FlipXY      = RotateNoneFlipNone,
  28.   Rotate270FlipXY      = Rotate90FlipNone
  29. } RotateFlipType;
  30.  
  31.  
  32. HBITMAP FlipBitmap(HBITMAP hBitmap, int Type = Rotate90FlipNone)
  33. {
  34.   // Initialize GDI+.
  35.   __int64 gdiplusStartupInput[3];
  36.   ULONG_PTR  gdiplusToken;
  37.   gdiplusStartupInput[0] = 1; gdiplusStartupInput[1] = 0;
  38.   if(GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL)) return 0;
  39.  
  40.   HBITMAP Result;
  41.   HANDLE GBitmap;
  42.  
  43.   GdipCreateBitmapFromHBITMAP(hBitmap, 0, &GBitmap);
  44.   GdipImageRotateFlip(GBitmap, Type);
  45.   GdipCreateHBITMAPFromBitmap(GBitmap, &Result, 0);
  46.   GdipDisposeImage(GBitmap);
  47.  
  48.   //shutdown GDI+
  49.   GdiplusShutdown(gdiplusToken);
  50.   return Result;
  51. }

Ejemplo de uso:


cpp
  1. Image1->Picture->Bitmap->Handle = FlipBitmap(Image1->Picture->Bitmap->Handle);
  2. Image1->Invalidate();

Por no hacer un mensaje muy extenso en código, la versión delphi la pongo en el siguiente.  |-)

PD: Un detalle que me gustaría añadir para las dos versiones. Si os fijáis, la inicialización y cierre de GDI+ se realiza en la función. Lo he puesto así para compactar el código. No es necesario hacerlo de esta forma. Si se va a hacer uso intensivo del GDI+ es pejor una inicialización global y cierre al terminar su uso, de esa forma evitamos la redundancia.


Saludos.


  • 0

#2 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.965 mensajes
  • LocationMadrid - España

Escrito 08 marzo 2012 - 05:33

Y en delphi:


delphi
  1. // GDI+ Flat API...
  2. function  GdiplusStartup(var GdiToken: DWORD; Startup, Output: PBYTE): Cardinal; stdcall external 'gdiplus';
  3. procedure GdiplusShutdown(GdiToken: DWORD); stdcall external 'gdiplus';
  4. function  GdipCreateBitmapFromHBITMAP(hbm: HBITMAP; hpal: HPALETTE; var GBitmap: THANDLE): Cardinal; stdcall external 'gdiplus';
  5. function  GdipCreateHBITMAPFromBitmap(GBitmap: THANDLE; var hBitmap: HBITMAP; BKColor: DWORD): DWORD; stdcall external 'gdiplus';
  6. function  GdipDisposeImage(image: THANDLE): Cardinal; stdcall external 'gdiplus';
  7. function  GdipImageRotateFlip(image: THANDLE; rfType: Cardinal): Cardinal; stdcall external 'gdiplus';
  8.  
  9. type
  10.   RotateFlipType = (
  11.   RotateNoneFlipNone,
  12.   Rotate90FlipNone,
  13.   Rotate180FlipNone,
  14.   Rotate270FlipNone,
  15.   RotateNoneFlipX,
  16.   Rotate90FlipX,
  17.   Rotate180FlipX,
  18.   Rotate270FlipX,
  19.   RotateNoneFlipY      = Rotate180FlipX,
  20.   Rotate90FlipY        = Rotate270FlipX,
  21.   Rotate180FlipY      = RotateNoneFlipX,
  22.   Rotate270FlipY      = Rotate90FlipX,
  23.   RotateNoneFlipXY    = Rotate180FlipNone,
  24.   Rotate90FlipXY      = Rotate270FlipNone,
  25.   Rotate180FlipXY      = RotateNoneFlipNone,
  26.   Rotate270FlipXY      = Rotate90FlipNone
  27. );
  28.  
  29. function FlipBitmap(Bitmap: HBITMAP; FlipType: RotateFlipType = Rotate90FlipNone): HBITMAP;
  30. var
  31.   GBitmap: THANDLE;
  32.   gdiplusToken: DWORD;
  33.   GdiPlusStartupInput: array[0..1] of int64;
  34. begin
  35.   // Inicializamos GDI+.
  36.   GdiPlusStartupInput[0]:= 1; GdiPlusStartupInput[1]:= 0;
  37.   if GdiplusStartup(gdiplusToken, @GdiPlusStartupInput, nil) <> 0 then exit;
  38.  
  39.   GdipCreateBitmapFromHBITMAP(Bitmap, 0, GBitmap);
  40.   GdipImageRotateFlip(GBitmap, CARDINAL(FlipType));
  41.   GdipCreateHBITMAPFromBitmap(GBitmap, Result, 0);
  42.   GdipDisposeImage(GBitmap);
  43.  
  44.   // Shutdown GDI+
  45.   GdiplusShutdown(gdiplusToken);
  46. end;

Ejemplo de uso:

delphi
  1. Image1.Picture.Bitmap.Handle:= FlipBitmap(Image1.Picture.Bitmap.Handle);

Espero que el ejemplo os sea de utilidad.



Saludos.
  • 0

#3 ELKurgan

ELKurgan

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 557 mensajes
  • LocationEspaña

Escrito 09 marzo 2012 - 12:26

Como siempre, maestro escafandra, código útil, claro y entendible

Haría falta un emoticón de quitarse el sombrero ante estas cosas (y)
  • 0