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