Answered by:
How to copy original graphics to a temporary graphics?

Question
-
Hi,
I'm trying to do alphablend by following this thread: http://social.msdn.microsoft.com/Forums/en-US/netfxcompact/thread/4c7b1975-d9b8-40e6-9497-aad8cfc3a09d
According to the poster:
// Copy original graphics into temp graphics to see the background through the image
gx.CopyTo(gxBuffer, width, height);I do not know where can I get the CopyTo method..or how to use it. Can someone please guide me?
Thanks!
Wednesday, September 21, 2011 4:35 AM
Answers
-
Hello,
I think this should be copy a graphics object into another graphics. When can copy them though a the BitBlt function, like this:
[DllImport("coredll.dll")] public static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop); public void CopyGraphics(Graphics scr, Graphics dest, int width, int height) { IntPtr scrhand = scr.GetHdc(); IntPtr desthand = dest.GetHdc(); BitBlt(desthand, 0, 0, width, height, scrhand, 0, 0, 0x00CC0020); }
I hope my suggestions can help you to solve this problem.
Best regards,
Jesse
Jesse Jiang [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
- Marked as answer by deejay220989 Friday, September 23, 2011 6:37 AM
Friday, September 23, 2011 6:25 AM -
I think Jesse has provided sufficient information for you. Well, you can also refer the following codes which also include the design time methods.
If you are also trying to create a design time control, the method would give you a better looking object when you are designing on VS2008.
#region ===== Copy Graphics ===== /// <summary> /// Copy source <see cref="System.Drawing.Graphics"/> to destination <see cref="System.Drawing.Graphics"/> with specified width and height /// </summary> /// <param name="gxSrc">The soruce graphic object</param> /// <param name="gxDst">The destination graphic object</param> /// <param name="width">The copy width</param> /// <param name="height">The copy height</param> public static void CopyTo(this Graphics gxSrc, Graphics gxDst, int width, int height) { gxSrc.CopyTo(gxDst, new Rectangle(0,0,width,height)); } /// <summary> /// Copy source <see cref="System.Drawing.Graphics"/> to destination <see cref="System.Drawing.Graphics"/> with specified width and height /// </summary> /// <param name="gxSrc">The soruce graphic object</param> /// <param name="gxDst">The destination graphic object</param> /// <param name="bounds">The copy bounds</param> public static void CopyTo(this Graphics gxSrc, Graphics gxDst, Rectangle bounds) { IntPtr dstDc = gxDst.GetHdc(); IntPtr srcDc = gxSrc.GetHdc(); if (Environment.OSVersion.Platform == PlatformID.WinCE) NativeMethods.BitBltCE(dstDc, 0, 0, bounds.Width, bounds.Height, srcDc, bounds.X, bounds.Y, (uint)TernaryRasterOperations.SRCCOPY); else NativeMethods.BitBltWin(dstDc, 0, 0, bounds.Width, bounds.Height, srcDc, bounds.X, bounds.Y, (uint)TernaryRasterOperations.SRCCOPY); gxSrc.ReleaseHdc(srcDc); gxDst.ReleaseHdc(dstDc); } #endregion #region ===== Draw Alpha ===== /// <summary> /// Draws an image with opacity /// </summary> /// <param name="gxDst">The destination graphics</param> /// <param name="image">The sourece image</param> /// <param name="opacity">The opacity value</param> /// <param name="x">The drawing x location</param> /// <param name="y">The drawing y location</param> public static void DrawAlpha(this Graphics gxDst, Image image, byte opacity, int x, int y) { gxDst.DrawAlpha(image, opacity, new Rectangle(x, y, image.Width, image.Height)); } /// <summary> /// Draws an image with opacity /// </summary> /// <param name="gxDst">The destination graphics</param> /// <param name="image">The sourece image</param> /// <param name="opacity">The opacity value</param> /// <param name="destRect">The destination rectangle. The image will fit into this rectangle.</param> public static void DrawAlpha(this Graphics gxDst, Image image, byte opacity, Rectangle destRect) { if (Environment.OSVersion.Platform == PlatformID.WinCE) { try { using (Graphics gxSrc = Graphics.FromImage(image)) { IntPtr hdcDst = gxDst.GetHdc(); IntPtr hdcSrc = gxSrc.GetHdc(); BlendFunction blendFunction = new BlendFunction { BlendOp = (byte)BlendOperation.AC_SRC_OVER, // Only supported blend operation BlendFlags = (byte)BlendFlags.Zero, // Documentation says put 0 here SourceConstantAlpha = opacity, // Constant alpha factor AlphaFormat = (byte)0 // Don't look for per pixel alpha }; NativeMethods.AlphaBlendCE( hdcDst, destRect.X, destRect.Y, destRect.Width, destRect.Height, hdcSrc, 0, 0, image.Width, image.Height, blendFunction); gxDst.ReleaseHdc(hdcDst); // Required cleanup to GetHdc() gxSrc.ReleaseHdc(hdcSrc); // Required cleanup to GetHdc() return; } } catch (Exception ex) { throw new BCD.ComponentModel.Win32Exception(ex); } } DrawAlphaWin(gxDst, image, opacity, destRect); } /// <summary> /// Draw Alpha Blending in design mode /// </summary> /// <param name="gxDst">The destination graphics</param> /// <param name="image">The sourece image</param> /// <param name="opacity">The opacity value</param> /// <param name="destRect">The destination rectangle. The image will fit into this rectangle.</param> internal static void DrawAlphaWin(this Graphics gxDst, Image image, byte opacity, Rectangle destRect) { // cheat the design time to create a bitmap with an alpha channel using (Bitmap tempBitmap = new Bitmap(image.Width, image.Height, (PixelFormat)PixelFormatID.PixelFormat32bppARGB)) { // copy the original image using (Graphics tempGx = Graphics.FromImage(tempBitmap)) { tempGx.DrawImage(image, 0, 0); } // Lock the bitmap's bits. Rectangle rect = new Rectangle(0, 0, tempBitmap.Width, tempBitmap.Height); System.Drawing.Imaging.BitmapData bmpData = tempBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, (PixelFormat)PixelFormatID.PixelFormat32bppARGB); // Get the address of the first line. IntPtr ptr = bmpData.Scan0; // Declare an array to hold the bytes of the bitmap. // This code is specific to a bitmap with 32 bits per pixels. int bytes = tempBitmap.Width * tempBitmap.Height * 4; byte[] argbValues = new byte[bytes]; // Copy the ARGB values into the array. System.Runtime.InteropServices.Marshal.Copy(ptr, argbValues, 0, bytes); // Set every alpha value to the given transparency. for (int counter = 3; counter < argbValues.Length; counter += 4) { argbValues[counter] = opacity; } // Copy the ARGB values back to the bitmap System.Runtime.InteropServices.Marshal.Copy(argbValues, 0, ptr, bytes); // Unlock the bits. tempBitmap.UnlockBits(bmpData); using (ImageAttributes attr = new ImageAttributes()) { attr.SetColorKey(Color.Black, Color.Black); //gxDst.DrawImage(tempBitmap, x, y); gxDst.DrawImage( tempBitmap, new Rectangle(destRect.X, destRect.Y, destRect.Width, destRect.Height), 0, 0, tempBitmap.Width, tempBitmap.Height, GraphicsUnit.Pixel, attr); } } }
Elvis Hsu
Senior Software Engineer at Barcode Dynamics Australia
Find me at Linkedin- Proposed as answer by Elvis Hsu Friday, September 23, 2011 6:41 AM
- Marked as answer by deejay220989 Friday, September 23, 2011 7:04 AM
Friday, September 23, 2011 6:41 AM
All replies
-
Hello,
I think this should be copy a graphics object into another graphics. When can copy them though a the BitBlt function, like this:
[DllImport("coredll.dll")] public static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop); public void CopyGraphics(Graphics scr, Graphics dest, int width, int height) { IntPtr scrhand = scr.GetHdc(); IntPtr desthand = dest.GetHdc(); BitBlt(desthand, 0, 0, width, height, scrhand, 0, 0, 0x00CC0020); }
I hope my suggestions can help you to solve this problem.
Best regards,
Jesse
Jesse Jiang [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
- Marked as answer by deejay220989 Friday, September 23, 2011 6:37 AM
Friday, September 23, 2011 6:25 AM -
I think Jesse has provided sufficient information for you. Well, you can also refer the following codes which also include the design time methods.
If you are also trying to create a design time control, the method would give you a better looking object when you are designing on VS2008.
#region ===== Copy Graphics ===== /// <summary> /// Copy source <see cref="System.Drawing.Graphics"/> to destination <see cref="System.Drawing.Graphics"/> with specified width and height /// </summary> /// <param name="gxSrc">The soruce graphic object</param> /// <param name="gxDst">The destination graphic object</param> /// <param name="width">The copy width</param> /// <param name="height">The copy height</param> public static void CopyTo(this Graphics gxSrc, Graphics gxDst, int width, int height) { gxSrc.CopyTo(gxDst, new Rectangle(0,0,width,height)); } /// <summary> /// Copy source <see cref="System.Drawing.Graphics"/> to destination <see cref="System.Drawing.Graphics"/> with specified width and height /// </summary> /// <param name="gxSrc">The soruce graphic object</param> /// <param name="gxDst">The destination graphic object</param> /// <param name="bounds">The copy bounds</param> public static void CopyTo(this Graphics gxSrc, Graphics gxDst, Rectangle bounds) { IntPtr dstDc = gxDst.GetHdc(); IntPtr srcDc = gxSrc.GetHdc(); if (Environment.OSVersion.Platform == PlatformID.WinCE) NativeMethods.BitBltCE(dstDc, 0, 0, bounds.Width, bounds.Height, srcDc, bounds.X, bounds.Y, (uint)TernaryRasterOperations.SRCCOPY); else NativeMethods.BitBltWin(dstDc, 0, 0, bounds.Width, bounds.Height, srcDc, bounds.X, bounds.Y, (uint)TernaryRasterOperations.SRCCOPY); gxSrc.ReleaseHdc(srcDc); gxDst.ReleaseHdc(dstDc); } #endregion #region ===== Draw Alpha ===== /// <summary> /// Draws an image with opacity /// </summary> /// <param name="gxDst">The destination graphics</param> /// <param name="image">The sourece image</param> /// <param name="opacity">The opacity value</param> /// <param name="x">The drawing x location</param> /// <param name="y">The drawing y location</param> public static void DrawAlpha(this Graphics gxDst, Image image, byte opacity, int x, int y) { gxDst.DrawAlpha(image, opacity, new Rectangle(x, y, image.Width, image.Height)); } /// <summary> /// Draws an image with opacity /// </summary> /// <param name="gxDst">The destination graphics</param> /// <param name="image">The sourece image</param> /// <param name="opacity">The opacity value</param> /// <param name="destRect">The destination rectangle. The image will fit into this rectangle.</param> public static void DrawAlpha(this Graphics gxDst, Image image, byte opacity, Rectangle destRect) { if (Environment.OSVersion.Platform == PlatformID.WinCE) { try { using (Graphics gxSrc = Graphics.FromImage(image)) { IntPtr hdcDst = gxDst.GetHdc(); IntPtr hdcSrc = gxSrc.GetHdc(); BlendFunction blendFunction = new BlendFunction { BlendOp = (byte)BlendOperation.AC_SRC_OVER, // Only supported blend operation BlendFlags = (byte)BlendFlags.Zero, // Documentation says put 0 here SourceConstantAlpha = opacity, // Constant alpha factor AlphaFormat = (byte)0 // Don't look for per pixel alpha }; NativeMethods.AlphaBlendCE( hdcDst, destRect.X, destRect.Y, destRect.Width, destRect.Height, hdcSrc, 0, 0, image.Width, image.Height, blendFunction); gxDst.ReleaseHdc(hdcDst); // Required cleanup to GetHdc() gxSrc.ReleaseHdc(hdcSrc); // Required cleanup to GetHdc() return; } } catch (Exception ex) { throw new BCD.ComponentModel.Win32Exception(ex); } } DrawAlphaWin(gxDst, image, opacity, destRect); } /// <summary> /// Draw Alpha Blending in design mode /// </summary> /// <param name="gxDst">The destination graphics</param> /// <param name="image">The sourece image</param> /// <param name="opacity">The opacity value</param> /// <param name="destRect">The destination rectangle. The image will fit into this rectangle.</param> internal static void DrawAlphaWin(this Graphics gxDst, Image image, byte opacity, Rectangle destRect) { // cheat the design time to create a bitmap with an alpha channel using (Bitmap tempBitmap = new Bitmap(image.Width, image.Height, (PixelFormat)PixelFormatID.PixelFormat32bppARGB)) { // copy the original image using (Graphics tempGx = Graphics.FromImage(tempBitmap)) { tempGx.DrawImage(image, 0, 0); } // Lock the bitmap's bits. Rectangle rect = new Rectangle(0, 0, tempBitmap.Width, tempBitmap.Height); System.Drawing.Imaging.BitmapData bmpData = tempBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, (PixelFormat)PixelFormatID.PixelFormat32bppARGB); // Get the address of the first line. IntPtr ptr = bmpData.Scan0; // Declare an array to hold the bytes of the bitmap. // This code is specific to a bitmap with 32 bits per pixels. int bytes = tempBitmap.Width * tempBitmap.Height * 4; byte[] argbValues = new byte[bytes]; // Copy the ARGB values into the array. System.Runtime.InteropServices.Marshal.Copy(ptr, argbValues, 0, bytes); // Set every alpha value to the given transparency. for (int counter = 3; counter < argbValues.Length; counter += 4) { argbValues[counter] = opacity; } // Copy the ARGB values back to the bitmap System.Runtime.InteropServices.Marshal.Copy(argbValues, 0, ptr, bytes); // Unlock the bits. tempBitmap.UnlockBits(bmpData); using (ImageAttributes attr = new ImageAttributes()) { attr.SetColorKey(Color.Black, Color.Black); //gxDst.DrawImage(tempBitmap, x, y); gxDst.DrawImage( tempBitmap, new Rectangle(destRect.X, destRect.Y, destRect.Width, destRect.Height), 0, 0, tempBitmap.Width, tempBitmap.Height, GraphicsUnit.Pixel, attr); } } }
Elvis Hsu
Senior Software Engineer at Barcode Dynamics Australia
Find me at Linkedin- Proposed as answer by Elvis Hsu Friday, September 23, 2011 6:41 AM
- Marked as answer by deejay220989 Friday, September 23, 2011 7:04 AM
Friday, September 23, 2011 6:41 AM -
Hi Elvis!
I thought you were no longer active here..thank God XD
Btw, I would like to ask an alphablend question.
Is it possible to alphablend two controls? For example, I have two controls, A and B where A will always be on top of B. When A move towards B, I would like to perform alphablend.
I've tried it and it does not work :(.
Thanks!
Friday, September 23, 2011 7:04 AM -
I believe what you meant is to intersect two controls? one is on top of another one?
For example, you would like to perform a 'drag and drop' action and when you drag cross over top of another control you want to alphablend the control you are dragging? Have you tried to use Control.CreateGraphics method and copy that graphics object and alhpablend it with the one you are dragging?
Elvis Hsu
Senior Software Engineer at Barcode Dynamics Australia
Find me at LinkedinFriday, September 23, 2011 7:23 AM -
I believe what you meant is to intersect two controls? one is on top of another one?
For example, you would like to perform a 'drag and drop' action and when you drag cross over top of another control you want to alphablend the control you are dragging? Have you tried to use Control.CreateGraphics method and copy that graphics object and alhpablend it with the one you are dragging?
Elvis Hsu
Senior Software Engineer at Barcode Dynamics Australia
Find me at Linkedin
Hi,Yes, what I meant is to alphablend when they intersect. I have not tried you method you suggested.
I'll let you know after I've tried it. I hope you'll still be here to advice me :)
Thanks!
Friday, September 23, 2011 7:26 AM -
Oh, if you implement "IControlBackground" interface (Have a look at here http://christian-helle.blogspot.com/2008/01/transparent-controls-in-netcf.html)
and it should be easier to do what you want...
Elvis Hsu
Senior Software Engineer at Barcode Dynamics Australia
Find me at LinkedinFriday, September 23, 2011 7:33 AM -
Oh, if you implement "IControlBackground" interface (Have a look at here http://christian-helle.blogspot.com/2008/01/transparent-controls-in-netcf.html)
and it should be easier to do what you want...
Elvis Hsu
Senior Software Engineer at Barcode Dynamics Australia
Find me at Linkedin
That's just basically copying the background, which is the parent (panel or form) right? But I guess if I want to alphablend two controls when they intersect, I need the Graphics information of the other control..correct?Friday, September 23, 2011 7:41 AM -
Yes, you are correct however if you want to cross many controls, I would suggest to get a snapshot of the screen (use BitBlt method) and paint and blend your control on the snapshot bitmap (as background image). So it will look like the control is on top of other controls. Does it make sense to you?
Elvis Hsu
Senior Software Engineer at Barcode Dynamics Australia
Find me at LinkedinFriday, September 23, 2011 8:03 AM -
Yes, you are correct however if you want to cross many controls, I would suggest to get a snapshot of the screen (use BitBlt
method) and paint and blend your control on the snapshot bitmap (as background image). So it will look like the control is on top of other controls. Does it make sense to you?
Elvis Hsu
Senior Software Engineer at Barcode Dynamics Australia
Find me at Linkedin
Yes, in fact it will cross alot of controls..which is why I'm wondering if implementing alphablend is even possible for my project.How can I use BitBlt to get a screenshot? Using the CAPTUREBLT?
Friday, September 23, 2011 8:13 AM -
I think I need to use the GetDC function..according to http://www.bobpowell.net/capture.htmFriday, September 23, 2011 8:18 AM