Hola invitado         31 Jul, 2010 - 07:33
Menú principal
 
Ads
 
Patrocinadores
 
Anuncios
 
© 2009 PortalFox
Dibujar imágenes rotadas con GDI+ (Cesar Chalom) Traducción lecturas 3320
 Enviado por amby en Miércoles, 25 Octubre, 2006
Artículos En este escrito tenemos la clave sobre cómo colocar marcas de agua u otras etiquetas rotadas en informes VFP 9.0. Cesar Chalom combina el empleo de GDI+ con los beneficios que aporta el nuevo motor de informes en VFP 9.0. Muy sencillo y muy práctico, ¡Gracias Cesar!

Dibujar imágenes rotadas con GDI+

Artículo original: DRAW ROTATED STRINGS WITH GDIPLUS-X
http://weblogs.foxite.com/cesarchalom/archive/2006/08/30/2388.aspx
Autor: Cesar Chalom (http://weblogs.foxite.com/cesarchalom)
Traducido por: Ana María Bisbé York (amby@telefonica.net)
Para: PortalFox (http://www.portalfox.com)


GDI+ ofrece muchas formas para dibujar objetos rotados, como imágenes, cadenas y formas. Básicamente, necesitamos hacer una transformación en traslación de la localización del texto, y luego una transformación en rotación hasta el ángulo necesario, y luego, escribir el texto como si estuviéramos escribiendo normalmente.

Esta es la definición encontrada en MSDN: "La operación de rotación consiste en multiplicación matriz a matriz cuyos elementos se derivan del parámetro del ángulo. Este método aplica la rotación como anexo a la transformación de la matriz."

IMPORTANTE

Todos los ejemplos a continuación utilizan la nueva biblioteca GDIPlus-X, que se encuentra aun en versión ALPHA; pero en realidad es estable y es segura para hacer la mayoría de las tareas de GDI+. Descargue la versión más recientemente librada desde Codeplex:

http://www.codeplex.com/Wiki/View.aspx?ProjectName=VFPX&title=GDIPlusX

* Inicializa la biblioteca GdiPlus-X 
_SCREEN.ADDPROPERTY("System", NEWOBJECT("xfcSystem", LOCFILE("system.vcx","vcx"))) 
WITH _SCREEN.SYSTEM.Drawing 
  * Crea un nuevo Bitmap vacío
  LOCAL loBmp as xfcBitmap
  loBmp = .Bitmap.New(180,180) 
  * Crea un objeto Graphics asociado al bitmap
  LOCAL loGfx as xfcGraphics
  loGfx = .Graphics.FromImage(loBmp) 
  * Limpia el fondo de la imagen con color azul claro
  loGfx.Clear(.Color.FromRgb(230,230,255)) 
  * Crea una broch sólida -SolidBrush de color rojo
  LOCAL loBrush AS xfcBrush
  loBrush = .SolidBrush.New(.COLOR.FromRgb(255,0,0))
  * La instrucción anterior pudo haber sido también
  * loBrush = .SolidBrush.New(.COLOR.FromARgb(255,255,0,0))
  * loBrush = .SolidBrush.New(.COLOR.Red) 
  * Crea un rectángulo - objeto Rectangle en el que va a dibujar el texto rotado
  LOCAL loRect AS xfcRectangle
  loRect = .Rectangle.New(0, 0, loBmp.Width, loBmp.Height) 
  * Crea un objeto string básico, luego configura sus propiedades
  LOCAL loStringFormat AS xfcStringFormat
  loStringFormat = .StringFormat.New()
  loStringFormat.ALIGNMENT = .StringAlignment.CENTER
  loStringFormat.LineAlignment = .StringAlignment.CENTER 
  * Crea un objeto fuente - Font 
  LOCAL loFont AS xfcFont
  loFont = .FONT.New("Verdana",16, .FontStyle.Bold, .GraphicsUnit.POINT) 
  * Después de crear todos los objetos necesarios, podemos aplicar la rotación
  * y dibujar el texto
  * Traslada y rota
  loGfx.TranslateTransform(loBmp.Width /2, loBmp.Height /2)
  loGfx.RotateTransform(-45) && angle of 45 degrees
  loGfx.TranslateTransform(-loBmp.Width /2, -loBmp.Height /2) 
  * Finalmente, dibuja la cadena
  loGfx.DrawString("Rotated Text" + CHR(13) + CHR(10) + "GDIPlus-X is COOL !!!", ;
  loFont, loBrush, loRect, loStringFormat) 
  * Reinicia la rotación
  loGfx.ResetTransform() 
  * Guarda la imagen en un archivo
  loBmp.Save("c:\rotated.png", .Imaging.ImageFormat.Png) 
ENDWITH 
* Muestra la imagen creada
RUN /N explorer.exe c:\rotated.png 

HORA DE JUGAR

Para el ejemplo anterior, usé un truco para rotar el texto al centro de la imagen, y no en el ángulo izquierdo, como es el comportamiento predeterminado. Ahora, es su turno de hacer algunas pruebas. Intente omitiendo las dos líneas que llaman Graphics.TranslateTransform, cambia el ángulo, cambie el ángulo, utilizando ángulos positivos y negativos, etc

* Traslación y rotación
loGfx.TranslateTransform(loBmp.Width /2, loBmp.Height /2) 
loGfx.RotateTransform(-45) && angle of 45 degrees 
loGfx.TranslateTransform(-loBmp.Width /2, -loBmp.Height /2)

En la carpeta "Samples" de la última versión de la biblioteca GDIPlus-X hay otro buen ejemplo, "Rotation.scx", en el cual se utilizó otra técnica de traslación. Todo el código está en el método "BeforeDraw" del objeto ImageCanVas.

¡DIBUJE CADENAS ROTADAS EN UN INFORME!

La origen real para este escrito, fue una pregunta hecha en FoxBrasil por mi amigo Emerson Santon Reed, cuando preguntó sobre crear una marca de agua de un gran texto rotado en 45 grados en un informe.

Entonces, mi parte fue adaptar el código GDI+ mostrado antes en la clase ReportListener y el Informe que el proporcionó.

Ejecute el código que aparece a continuación para ver un texto rotado centrado 45 grados en un informe.

* Crea un informe de ejemplo
LOCAL i
CREATE CURSOR dummy (fld1 c(20), fld2 c(15))
FOR i=1 TO 100
  INSERT INTO dummy VALUES ("ReportListener con GdiPlus-X", "Visite CodePlex")
ENDFOR
SELECT dummy
CREATE REPORT _testreport FROM dummy 
* Inicializa GdiPlus-X
_SCREEN.ADDPROPERTY("System", NEWOBJECT("xfcSystem", LOCFILE("system.vcx","vcx"))) 
* Carga la clase Listener 
LOCAL loreportlistener
loreportlistener = CREATEOBJECT("MyReportListener")
loreportlistener.LISTENERTYPE = 1 
* Llama al informe empleando nuestro listener
REPORT FORM _testreport OBJECT loreportlistener
USE IN dummy
RETURN 

DEFINE CLASS myreportlistener AS _reportlistener OF ;
  ADDBS(HOME()) + "FFC\" + "_ReportListener.VCX"
  newpage = .T.
  ogdigraphics = NULL 

  FUNCTION BEFOREREPORT
    DODEFAULT()
    This.ogdigraphics = _SCREEN.SYSTEM.drawing.graphics.new()
  ENDFUNC 

  FUNCTION BEFOREBAND(nbandobjcode, nfrxrecno)
    #DEFINE frx_objcod_pageheader 1
    IF nbandobjcode==frx_objcod_pageheader
      This.newpage = .T.
      IF NOT This.issuccessor
        This.sharedgdiplusgraphics = This.GDIPLUSGRAPHICS
      ENDIF
      This.ogdigraphics.handle = This.sharedgdiplusgraphics
    ENDIF
    DODEFAULT(nbandobjcode, nfrxrecno)
  ENDFUNC 

  PROCEDURE RENDER(nfrxrecno,;
    nleft,ntop,nwidth,nheight,;
    nobjectcontinuationtype, ;
    ccontentstoberendered, gdiplusimage)
    WITH _SCREEN.SYSTEM.drawing
      IF This.newpage
        * Crea un objeto SolidBrush de color gris
        LOCAL lobrush AS xfcbrush
        lobrush = .solidbrush.new(.COLOR.fromrgb(210,128,128)) 
        * Crea un objeto Rectangle en el que va a ser dibujado el texto rotado
        LOCAL lorect AS xfcrectangle
        lorect = .rectangle.new(0, 0, This.sharedpagewidth,;
          This.sharedpageheight) 
        * Crea un objeto string básico, luego configura sus propiedades
        LOCAL lostringformat AS xfcstringformat
        lostringformat = .stringformat.new()
        lostringformat.ALIGNMENT = .stringalignment.CENTER
        lostringformat.linealignment = .stringalignment.CENTER 
        * Crea un objeto fuente - Font 
        LOCAL lofont AS xfcfont
        lofont = .FONT.new("Verdana",48, 0, .graphicsunit.POINT) 
        * Traslada y rota
        This.ogdigraphics.translatetransform(This.sharedpagewidth/2,;
          This.sharedpageheight/2)
        This.ogdigraphics.rotatetransform(-45)
        This.ogdigraphics.translatetransform(-This.sharedpagewidth/2,;
          -This.sharedpageheight/2)
        This.ogdigraphics.drawstring("Rotated Text" +CHR(13)+CHR(10)+;
          "GDIPlus-X is COOL !!!", ;
          lofont, lobrush, lorect, lostringformat) 
        * Reinicia la rotación
        This.ogdigraphics.resettransform() 
        This.newpage = .F.
      ENDIF
    ENDWITH
    DODEFAULT(nfrxrecno,;
      nleft,ntop,nwidth,nheight,;
      nobjectcontinuationtype, ;
      ccontentstoberendered, gdiplusimage)
  ENDPROC
ENDDEFINE

Actualización 06-08-31

Para asegurarnos de que la marca de agua no será sobreescrita por controles opacos, el código a continuación muestra lo mismo que antes; pero este caso dibuja la marca de agua justo después de que la banda Pie ha sido totalmente generada. El color utilizado para este caso fue también cambiado de opaco a semitransparente, utilizando Alpha de 128 (0 = totalmente transparente, 255 = opaco). Entonces, he aquí la nueva clase  ReportListener para solucionar este problema:

DEFINE CLASS myreportlistener AS _reportlistener OF ;
  ADDBS(HOME()) + "FFC\" + "_ReportListener.VCX"
  ogdigraphics = NULL 

  FUNCTION BEFOREREPORT
    DODEFAULT()
    This.ogdigraphics = _SCREEN.SYSTEM.drawing.graphics.new()
  ENDFUNC 

  FUNCTION AFTERBAND(nbandobjcode, nfrxrecno)
    *-- Valores de las columnas de FRX OBJCODE 
    #DEFINE FRX_OBJCOD_TITLE 0
    #DEFINE FRX_OBJCOD_PAGEHEADER 1
    #DEFINE FRX_OBJCOD_COLHEADER 2
    #DEFINE FRX_OBJCOD_GROUPHEADER 3
    #DEFINE FRX_OBJCOD_DETAIL 4
    #DEFINE FRX_OBJCOD_GROUPFOOTER 5
    #DEFINE FRX_OBJCOD_COLFOOTER 6
    #DEFINE FRX_OBJCOD_PAGEFOOTER 7
    #DEFINE FRX_OBJCOD_SUMMARY 8
    #DEFINE FRX_OBJCOD_DETAILHEADER 9
    #DEFINE FRX_OBJCOD_DETAILFOOTER 10
    
    IF nbandobjcode==frx_objcod_pagefooter
      IF NOT This.issuccessor
        This.sharedgdiplusgraphics = This.GDIPLUSGRAPHICS
      ENDIF
      This.ogdigraphics.handle = This.sharedgdiplusgraphics
      
      WITH _SCREEN.SYSTEM.drawing
        * Crea un objeto SolidBrush de color rojo semi transparente 
        LOCAL lobrush AS xfcbrush
        lobrush = .solidbrush.new(.COLOR.fromArgb(128,255,128,128)) 

        * Crea un objeto Rectangle en el que va a ser dibujado el texto rotado
        LOCAL lorect AS xfcrectangle
        lorect = .rectangle.new(0, 0, This.sharedpagewidth,;
          This.sharedpageheight) 

        * Crea un objeto string básico, luego configura sus propiedades
        LOCAL lostringformat AS xfcstringformat
        lostringformat = .stringformat.new()
        lostringformat.ALIGNMENT = .stringalignment.CENTER
        lostringformat.linealignment = .stringalignment.CENTER 

        * Crea un objeto fuente - Font 
        LOCAL lofont AS xfcfont
        lofont = .FONT.new("Verdana",48, 0, .graphicsunit.POINT) 

        * Traslada y rota
        This.ogdigraphics.translatetransform(This.sharedpagewidth/2,;
          This.sharedpageheight/2)
        This.ogdigraphics.rotatetransform(-45)
        This.ogdigraphics.translatetransform(-This.sharedpagewidth/2,;
          -This.sharedpageheight/2)
        This.ogdigraphics.drawstring("Rotated Text" +CHR(13)+CHR(10)+;
          "GDIPlus-X is COOL !!!", ;
          lofont, lobrush, lorect, lostringformat) 

        * Reinicia la rotación
        This.ogdigraphics.resettransform() 

      ENDWITH
    ENDIF
    DODEFAULT(nBandObjCode, nFRXRecNo)
  ENDFUNC
ENDDEFINE

ENLACES RELACIONADOS

Artículo de Bill Wagner: http://www.ftponline.com/vsm/2002_10/online/csharp_bwagner_10_31_02

Página GdiPlusX en CodePlex: http://www.codeplex.com/Wiki/View.aspx?ProjectName=VFPX&title=GDIPlusX


 Versión imprimible  
Dibujar imágenes rotadas con GDI+ (Cesar Chalom) Traducción | Entrar/Crear una cuenta | 0 Comentarios
Los comentarios son propiedad de sus respectivos autores.
No somos responsables de su contenido.



Todas las marcas y los logos utilizados en este sitio son propiedad de sus respectivos dueños.
Los artículos, noticias y comentarios son propiedad y responsabilidad de sus respectivos autores.
Copyright © 2000-2010 PortalFox. Todos los derechos reservados.