2009-07-01

Change the shape of your pictures with GdiPlusX

The samples below use the Graphics.SetClip function to draw shaped borders in your pictures.

The trick here is to use the CombineMode.Xor enumeration, that forces the drawing to the external part of the shape, like in the samples below.

We'll be playing with the source image below:



Prerequisites
Visual FoxPro 9 and the GdiplusX library from VFPX 






Sample 1: Ellipse Shape

DO LOCFILE("System.App") WITH _SCREEN.SYSTEM.Drawing * get an image file LOCAL loBmp AS xfcBitMap m.loBmp = .BITMAP.FromFile(GETPICT()) * create a gfx object that will allow us to make the transformation LOCAL loGfx AS xfcGraphics m.loGfx = .Graphics.FromImage(m.loBmp) LOCAL lnWidth, lnHeight m.lnWidth = m.loBmp.WIDTH m.lnHeight = m.loBmp.HEIGHT * create graphicsPath object. LOCAL loClipPath AS xfcGraphicsPath m.loClipPath = .Drawing2d.GraphicsPath.New() * an Ellipse shape m.loClipPath.AddEllipse(0, 0, m.lnWidth, m.lnHeight) * set Clipping region to Path. * CombineMode enumeration * http://msdn.microsoft.com/en-us/library/system.Drawing.Drawing2d.CombineMode.aspx * CombineMode.xor - two Clipping regions are combined by taking only the areas * enclosed by one or the other region, but not both. m.loGfx.SetClip(m.loClipPath, ; _SCREEN.SYSTEM.Drawing.Drawing2d.CombineMode.xor) * fill Rectangle to demonstrate Clipping region. m.loGfx.FillRectangle( .Brushes.White, 0, 0, m.loBmp.WIDTH, m.loBmp.HEIGHT) * save the image to the disk and show m.loBmp.SAVE("Clipped.jpg", "image/jpeg") RUN /N Explorer.EXE Clipped.jpg ENDWITH

















Sample 2: Doughnut Shape


DO LOCFILE("System.App")
WITH _SCREEN.SYSTEM.Drawing
 * get an image file
 LOCAL loBmp AS xfcBitMap
 m.loBmp = .BITMAP.FromFile(GETPICT())
 * create a gfx object that will allow us to make the transformation
 LOCAL loGfx AS xfcGraphics
 m.loGfx = .Graphics.FromImage(m.loBmp)
 LOCAL lnWidth, lnHeight
 m.lnWidth  = m.loBmp.WIDTH
 m.lnHeight = m.loBmp.HEIGHT

 * create graphicsPath object.
 LOCAL loClipPath AS xfcGraphicsPath
 m.loClipPath = .Drawing2d.GraphicsPath.New()


 * a doughnut slice shape
 m.loClipPath.AddEllipse(0, 0, m.lnWidth, m.lnHeight * 2)
 m.loClipPath.AddEllipse(m.lnWidth / 4, m.lnHeight / 2, m.lnWidth / 2, m.lnHeight * 4)


 * set Clipping region to Path.
 * CombineMode enumeration
 * http://msdn.microsoft.com/en-us/library/system.Drawing.Drawing2d.CombineMode.aspx
 * CombineMode.xor - two Clipping regions are combined by taking only the areas 
 * enclosed by one or the other region, but not both. 
 m.loGfx.SetClip(m.loClipPath, ;
    _SCREEN.SYSTEM.Drawing.Drawing2d.CombineMode.xor)
 * fill Rectangle to demonstrate Clipping region.
 m.loGfx.FillRectangle( .Brushes.White, 0, 0, m.loBmp.WIDTH, m.loBmp.HEIGHT)
 * save the image to the disk and show
 m.loBmp.SAVE("Clipped.jpg", "image/jpeg")
 RUN /N Explorer.EXE Clipped.jpg
ENDWITH











Sample 3: Star Shape


DO LOCFILE("System.App")
WITH _SCREEN.SYSTEM.Drawing
 * get an image file
 LOCAL loBmp AS xfcBitMap
 m.loBmp = .BITMAP.FromFile(GETPICT())
 * create a gfx object that will allow us to make the transformation
 LOCAL loGfx AS xfcGraphics
 m.loGfx = .Graphics.FromImage(m.loBmp)
 LOCAL lnWidth, lnHeight
 m.lnWidth  = m.loBmp.WIDTH
 m.lnHeight = m.loBmp.HEIGHT

 * create graphicsPath object.
 LOCAL loClipPath AS xfcGraphicsPath
 m.loClipPath = .Drawing2d.GraphicsPath.New()



 * source for the star Drawing
 * http://www.java2s.com/code/vb/2d/graphicsPathdrawwithfillmodewinding.htm
 LOCAL lnRadius, lnpi, lnRadian72, N, lnEdges
 m.lnRadius  = m.lnHeight / 2
 m.lnpi   = 3.141592
 m.lnEdges  = 5
 m.lnRadian72 = (m.lnpi * 4.0 ) / m.lnEdges
 LOCAL laPoints(lnEdges)
 FOR m.N = 1 TO m.lnEdges
  m.laPoints(m.N) = .Point.New( ;
     + m.lnRadius * SIN( m.N * m.lnRadian72 ) + m.lnRadius, ;
     - m.lnRadius * COS( m.N * m.lnRadian72 ) + m.lnRadius )
 ENDFOR
 m.loClipPath.AddPolygon(@m.laPoints)
 * set the Clip mode to winding
 * Clipmode enumeration
 *http://msdn.microsoft.com/en-us/library/system.Drawing.Drawing2d.Fillmode.aspx
 m.loClipPath.Fillmode = _SCREEN.SYSTEM.Drawing.Drawing2d.Fillmode.winding

 * set Clipping region to Path.
 * CombineMode enumeration
 * http://msdn.microsoft.com/en-us/library/system.Drawing.Drawing2d.CombineMode.aspx
 * CombineMode.xor - two Clipping regions are combined by taking only the areas 
 * enclosed by one or the other region, but not both. 
 m.loGfx.SetClip(m.loClipPath, ;
    _SCREEN.SYSTEM.Drawing.Drawing2d.CombineMode.xor)
 * fill Rectangle to demonstrate Clipping region.
 m.loGfx.FillRectangle( .Brushes.White, 0, 0, m.loBmp.WIDTH, m.loBmp.HEIGHT)
 * save the image to the disk and show
 m.loBmp.SAVE("Clipped.jpg", "image/jpeg")
 RUN /N Explorer.EXE Clipped.jpg
ENDWITH








Notice that the only difference between the code samples is the shape definition !

No comments:

Post a Comment