Mezclar dos imagenes con GDIPlusX vfp

Post Original de Bo Durban, replicado

Blending Two Images Using GDIPlusX

Después de ver una publicación en los foros de Micrsoft. Me propuse intentar resolver cómo combinar dos imágenes con GDI +. Pude encontrar poca información en la web sobre cómo resolver este problema en particular, por lo que se me ocurrió mi propia técnica (con la excelente ayuda de Craig Boyd).
Aquí hay una muestra de imagen combinada y el código VFP / GDIPlusX que utilicé para crearla.

Paste this code into a PRG and run it. This code requires the GDIPlusX library from VFPX.
Local lcPict1, lcPict2

m.lcPict1 = Getpict()
If File(m.lcPict1)
   m.lcPict2 = Getpict()
   If File(m.lcPict2)
      ImageAlphaBlend(m.lcPict1, m.lcPict2)
   Endif
Endif

**********************************************************
Function ImageAlphaBlend(tcPictLeft, tcPictRight)
**********************************************************
* Author: Bo Durban *

   Local loColorMatrix As xfcCOlorMatrix
   Local loImageLeft As xfcImage
   Local loImageRight As xfcImage
   Local loBitmapPart As xfcBitmap
   Local loBitmapLeft As xfcBitmap
   Local laImageAttribs[1]
   Local loGfxLeft As xfcGraphics
   Local loGfxPart As xfcGraphics
   Local loGfxScreen As xfcGraphics
   Local lnAlphaSteps, lnBlendPercentage, lnWidthOpaque, lnStep, lnHeightImage, lnLeftStart

** Sets the number of Alpha blend steps used to render the blend.
** The max is 256. lower steps equals lower quality, but higher speed
   m.lnAlphaSteps = 128
** Sets the percentage of the image that is blended
   m.lnPercentageBlend = .75

   Dimension laImageAttribs[m.lnAlphaSteps]

** Requires the GDIPlusX library (version 1.20 beta)
** http://www.codeplex.com/VFPX/Release/ProjectReleases.aspx?ReleaseId=15083
   Do (Locfile("SYSTEM.APP"))
   With _Screen.System.Drawing

      m.loImageRight = .Image.FromFile(m.tcPictLeft)
      m.loImageLeft = .Image.FromFile(m.tcPictRight)

** Force the left image to be the same size as the right image
      m.loBitmapLeft = .Bitmap.New(m.loImageRight.Width, m.loImageRight.Height)
      m.loGfxLeft=.Graphics.FromImage(m.loBitmapLeft)
      m.loGfxLeft.Clear(.Color.Transparent)
      m.loGfxLeft.DrawImage(m.loImageLeft,0,0,m.loBitmapLeft.Width,m.loBitmapLeft.Height)

      m.lnWidthOpaque = m.loImageRight.Width * (1 - m.lnPercentageBlend) / 2
      m.lnWidthPart = Ceiling((m.loBitmapLeft.Width-m.lnWidthOpaque*2)/m.lnAlphaSteps)
      m.loBitmapPart = .Bitmap.New(m.lnWidthPart, m.loBitmapLeft.Height)
      m.loGfxPart=.Graphics.FromImage(m.loBitmapPart)
      m.loGfxPart.Clear(.Color.Transparent)

** Pre-fill ImageAttributes with Alpha ColorMatrix blend for performance
** The biggest advantage to doing this is if you were processing multiple
** set of images at a time, which we aren't doing here.
      m.loColorMatrix=.Imaging.ColorMatrix.New()

      For m.lnCurrentStep = 1 To m.lnAlphaSteps
         laImageAttribs[m.lnCurrentStep] = .Imaging.ImageAttributes.New()
         m.loColorMatrix.Matrix33 = m.lnCurrentStep/m.lnAlphaSteps
         laImageAttribs[m.lnCurrentStep].SetColorMatrix(m.loColorMatrix)
      Endfor

** Adjust these for preferred image quality vs. speed
*m.loGfxLeft.InterpolationMode = .Drawing2D.InterpolationMode.Default
*m.loGfxLeft.CompositingQuality = .Drawing2D.CompositingQuality.Default
*m.loGfxLeft.SmoothingMode = .Drawing2D.SmoothingMode.Default

** Use integers instead of floats for performance
      m.loGfxLeft.UsePrecision = .F.
** Minor speed increase accessing this property once
      m.lnHeightImage = m.loImageRight.Height

      For m.lnCurrentStep = 1 To m.lnAlphaSteps
         m.lnLeftStart = m.lnCurrentStep*m.lnWidthPart + m.lnWidthOpaque

** Draw partial right image to part
         m.loGfxPart.DrawImage(m.loImageRight, ;
            0,0,m.lnWidthPart,m.lnHeightImage, ;
            m.lnLeftStart,0,m.lnWidthPart,m.lnHeightImage, ;
            .GraphicsUnit.Pixel)

** Draw part to left image with Alpha blend
         m.loGfxLeft.DrawImage(m.loBitmapPart, ;
            m.lnLeftStart,0,m.lnWidthPart,m.lnHeightImage, ;
            0,0,m.lnWidthPart,m.lnHeightImage, ;
            .GraphicsUnit.Pixel, ;
            laImageAttribs[m.lnCurrentStep])

      Endfor

** Draw last opaque part of right image
      m.loGfxLeft.DrawImage(m.loImageRight, ;
         m.loImageRight.Width-m.lnWidthOpaque, 0, m.lnWidthOpaque, m.lnHeightImage, ;
         m.loImageRight.Width-m.lnWidthOpaque, 0, m.lnWidthOpaque, m.lnHeightImage, ;
         .GraphicsUnit.Pixel)

** Render to the screen
      m.loGfxScreen = .Graphics.FromHWnd(_Screen.HWnd)
      m.loGfxScreen.Clear(.Color.White)
      m.loGfxScreen.DrawImage(m.loBitmapLeft,0,0,1024,768)

** Or you can save it to a file
**m.loBitmapLeft.Save("MyBlendedImage.png")

   Endwith

   Return
Endfunc

Funte: http://web.archive.org/web/20101017154139/http://blog.moxiedata.com/PermaLink,guid,7876146a-96e0-47dd-b442-271cad494a5d.aspx

Deja un comentario