public static void DrawAlpha(Graphics gx, Bitmap image, byte transp, int x, int y) { using (Graphics gxSrc = Graphics.FromImage(image)) { IntPtr hdcDst = gx.GetHdc(); IntPtr hdcSrc = gxSrc.GetHdc(); BlendFunction blendFunction = new BlendFunction(); blendFunction.BlendOp = (byte)BlendOperation.AC_SRC_OVER; // Only supported blend operation blendFunction.BlendFlags = (byte)BlendFlags.Zero; // Documentation says put 0 here blendFunction.SourceConstantAlpha = transp; // Constant alpha factor blendFunction.AlphaFormat = (byte)0; // Don't look for per pixel alpha DrawingAPI.AlphaBlend(hdcDst, x, y, image.Width, image.Height, hdcSrc, 0, 0, image.Width, image.Height, blendFunction); gx.ReleaseHdc(hdcDst); // Required cleanup to GetHdc() gxSrc.ReleaseHdc(hdcSrc); // Required cleanup to GetHdc() } }
/// <summary> /// Draws this image into the given Graphics object. /// If the image contains alpha channel, it will used with the buffer. /// If an Alpha value is set (> 0), the image will also be alpha blended with the buffer. /// </summary> /// <param name="gx">The Graphics object to use for drawing.</param> /// <param name="bounds">The bounds where to draw.</param> public void Draw(Graphics gx, Rectangle bounds) { ImageInfo imgInfo; _image.GetImageInfo(out imgInfo); if (_alpha == 0) { // Draw the image, with alpha channel if any IntPtr hdcDest = gx.GetHdc(); Rectangle dstRect = new Rectangle(bounds.X, bounds.Y, (int)imgInfo.Width + bounds.X, (int)imgInfo.Height + bounds.Y); _image.Draw(hdcDest, ref dstRect, IntPtr.Zero); gx.ReleaseHdc(hdcDest); } else { // Creates buffer on demand if (_buffer == null) _buffer = new Bitmap((int)imgInfo.Width, (int)imgInfo.Height, PixelFormat.Format32bppRgb); using (Graphics gxBuffer = Graphics.FromImage(_buffer)) { IntPtr hdcBuffer = gxBuffer.GetHdc(); IntPtr hdcOrg = gx.GetHdc(); // Copy original DC into Buffer DC to see the background through the image DrawingAPI.BitBlt(hdcBuffer, 0, 0, (int)imgInfo.Width, (int)imgInfo.Height, hdcOrg, bounds.X, bounds.Y, DrawingAPI.SRCCOPY); // Draw the image, with alpha channel if any Rectangle dstRect = new Rectangle(0, 0, (int)imgInfo.Width, (int)imgInfo.Height); _image.Draw(hdcBuffer, ref dstRect, IntPtr.Zero); // Alpha blend image BlendFunction blendFunction = new BlendFunction(); blendFunction.BlendOp = (byte)BlendOperation.AC_SRC_OVER; // Only supported blend operation blendFunction.BlendFlags = (byte)BlendFlags.Zero; // Documentation says put 0 here blendFunction.SourceConstantAlpha = (byte)_alpha; // Constant alpha factor blendFunction.AlphaFormat = 0; // Don't look for per pixel alpha DrawingAPI.AlphaBlend(hdcOrg, bounds.X, bounds.Y, bounds.Width, bounds.Height, hdcBuffer, 0, 0, (int)imgInfo.Width, (int)imgInfo.Height, blendFunction); gx.ReleaseHdc(hdcOrg); // Required cleanup to GetHdc() gxBuffer.ReleaseHdc(hdcBuffer); // Required cleanup to GetHdc() } } }
public static extern bool AlphaBlend(IntPtr hdcDest, Int32 nXDest, Int32 nYDest, Int32 nWidthDst, Int32 nHeightDst, IntPtr hdcSrc, Int32 nXSrc, Int32 nYSrc, Int32 nWidthSrc, Int32 nHeightSrc, BlendFunction blendFunction);