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
EndfuncFunte: http://web.archive.org/web/20101017154139/http://blog.moxiedata.com/PermaLink,guid,7876146a-96e0-47dd-b442-271cad494a5d.aspx