Copied from:
http://web.archive.org/web/20101017154139/http://blog.moxiedata.com/PermaLink,guid,7876146a-96e0-47dd-b442-271cad494a5d.aspx
Blending Two Images Using GDIPlusX
After seeing a post on the Micrsoft forums. I set out to try and solve how to blend two images using GDI+. I could find little information on the web on how to solve this particular problem, so I came up with my own technique (with some excellent help from Craig Boyd).
Here is a sample blended image and the VFP / GDIPlusX code that I used to create it.
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
No comments:
Post a Comment