/// <summary>
        /// Captures a screenshot of a window using the Windows DWM
        /// </summary>
        /// <param name="handle">handle of the window to capture</param>
        /// <returns>the captured window image</returns>
        public static Image CaptureWithDWM(IntPtr handle)
        {
            FileSystem.AppendDebug("Capturing with DWM");
            Image  windowImage = null;
            Bitmap redBGImage  = null;

            Rectangle windowRect = NativeMethods.GetWindowRectangle(handle);

            windowRect = NativeMethods.MaximizedWindowFix(handle, windowRect);

            if (Engine.HasAero && Engine.conf.ActiveWindowClearBackground)
            {
                windowImage = CaptureWindowWithTransparencyDWM(handle, windowRect, out redBGImage, Engine.conf.ActiveWindowCleanTransparentCorners);
            }

            if (windowImage == null)
            {
                FileSystem.AppendDebug("Standard capture (no transparency)");
                windowImage = CaptureRectangle(windowRect);
            }

            if (Engine.conf.ActiveWindowCleanTransparentCorners)
            {
                Image result = RemoveCorners(handle, windowImage, redBGImage, windowRect);
                if (result != null)
                {
                    windowImage = result;
                }
            }

            if (windowImage != null)
            {
                if (Engine.conf.ActiveWindowIncludeShadows)
                {
                    // Draw shadow manually to be able to have shadows in every case
                    windowImage = GraphicsMgr.AddBorderShadow((Bitmap)windowImage, true);
                    Point shadowOffset = GraphicsMgr.ShadowOffset;
                    windowRect.X -= shadowOffset.X;
                    windowRect.Y -= shadowOffset.Y;
                }

                if (Engine.conf.ActiveWindowShowCheckers)
                {
                    windowImage = ImageEffects.DrawCheckers(windowImage);
                }

                if (Engine.conf.ShowCursor)
                {
                    DrawCursor(windowImage, windowRect.Location);
                }
            }

            return(windowImage);
        }
 public static void CopyImageToClipboard(Image img)
 {
     if (img != null)
     {
         using (Image img2 = ImageEffects.FillBackground(img, Engine.conf.ClipboardBackgroundColor))
         {
             try
             {
                 Clipboard.SetImage(img2);
                 //ImageOutput.PrepareClipboardObject();
                 //ImageOutput.CopyToClipboard(img2);
             }
             catch (Exception ex)
             {
                 FileSystem.AppendDebug("Error while copying image to clipboard", ex);
             }
         }
     }
 }
        /// <summary>
        /// Function to return the file path of a captured image. ImageFormat is based on length of the image.
        /// </summary>
        /// <param name="img">The actual image</param>
        /// <param name="filePath">The path to where the image will be saved</param>
        /// <returns>Returns the file path to a screenshot</returns>
        public static string SaveImage(ref WorkerTask task)
        {
            Image  img      = task.MyImage;
            string filePath = task.LocalFilePath;

            if (!string.IsNullOrEmpty(filePath))
            {
                img = ImageEffects.ApplySizeChanges(img);
                img = ImageEffects.ApplyScreenshotEffects(img);
                if (task.Job != WorkerTask.Jobs.UploadFromClipboard || !Engine.conf.WatermarkExcludeClipboardUpload)
                {
                    img = ImageEffects.ApplyWatermark(img);
                }

                long size = (long)Engine.conf.SwitchAfter * 1024;

                MemoryStream ms = null;

                GraphicsMgr.SaveImageToMemoryStreamOptions opt = new GraphicsMgr.SaveImageToMemoryStreamOptions(img, Engine.zImageFileFormat);
                opt.GIFQuality             = Engine.conf.GIFQuality;
                opt.JpgQuality             = Engine.conf.JpgQuality;
                opt.MakeJPGBackgroundWhite = Engine.conf.MakeJPGBackgroundWhite;

                try
                {
                    ms = GraphicsMgr.SaveImageToMemoryStream(opt);

                    if (ms.Length > size && size != 0)
                    {
                        opt.MyImageFileFormat = Engine.zImageFileFormatSwitch;
                        ms       = GraphicsMgr.SaveImageToMemoryStream(opt);
                        filePath = Path.ChangeExtension(filePath, Engine.zImageFileFormatSwitch.Extension);
                    }

                    if (!Directory.Exists(Path.GetDirectoryName(filePath)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(filePath));
                    }

                    int retry = 3;
                    while (retry > 0 && !File.Exists(filePath))
                    {
                        using (FileStream fi = File.Create(filePath))
                        {
                            if (retry < 3)
                            {
                                System.Threading.Thread.Sleep(1000);
                            }
                            FileSystem.AppendDebug(string.Format("Writing image {0}x{1} to {2}", img.Width, img.Height, filePath));
                            ms.WriteTo(fi);
                            retry--;
                        }
                    }
                }
                catch (Exception ex)
                {
                    FileSystem.AppendDebug("Error while saving image", ex);
                }
                finally
                {
                    if (ms != null)
                    {
                        ms.Dispose();
                    }
                }
            }

            task.UpdateLocalFilePath(filePath);
            return(filePath);
        }
        /// <summary>
        /// Captures a screenshot of a window using Windows GDI. Captures transparency.
        /// </summary>
        /// <param name="handle">handle of the window to capture</param>
        /// <returns>the captured window image</returns>
        private static Image CaptureWindowWithTransparencyGDI(IntPtr handle, Rectangle windowRect)
        {
            Image  windowImage = null;
            Bitmap whiteBGImage = null, blackBGImage = null, white2BGImage = null;

            try
            {
                using (new Freeze(handle))
                    using (Form form = new Form())
                    {
                        form.BackColor       = Color.White;
                        form.FormBorderStyle = FormBorderStyle.None;
                        form.ShowInTaskbar   = false;

                        int offset = Engine.conf.ActiveWindowIncludeShadows && !NativeMethods.IsWindowMaximized(handle) ? 20 : 0;

                        windowRect = windowRect.AddMargin(offset);
                        windowRect.Intersect(GraphicsMgr.GetScreenBounds());

                        NativeMethods.ShowWindow(form.Handle, (int)NativeMethods.WindowShowStyle.ShowNormalNoActivate);
                        NativeMethods.SetWindowPos(form.Handle, handle, windowRect.X, windowRect.Y, windowRect.Width, windowRect.Height, NativeMethods.SWP_NOACTIVATE);
                        Application.DoEvents();
                        whiteBGImage = (Bitmap)CaptureRectangle(NativeMethods.GetDesktopWindow(), windowRect);

                        form.BackColor = Color.Black;
                        Application.DoEvents();
                        blackBGImage = (Bitmap)CaptureRectangle(NativeMethods.GetDesktopWindow(), windowRect);

                        if (!Engine.conf.ActiveWindowGDIFreezeWindow)
                        {
                            form.BackColor = Color.White;
                            Application.DoEvents();
                            white2BGImage = (Bitmap)CaptureRectangle(NativeMethods.GetDesktopWindow(), windowRect);
                        }
                    }

                if (Engine.conf.ActiveWindowGDIFreezeWindow || whiteBGImage.AreBitmapsEqual(white2BGImage))
                {
                    windowImage = GraphicsMgr.ComputeOriginal(whiteBGImage, blackBGImage);
                }
                else
                {
                    windowImage = (Image)whiteBGImage.Clone();
                }
            }
            finally
            {
                if (whiteBGImage != null)
                {
                    whiteBGImage.Dispose();
                }
                if (blackBGImage != null)
                {
                    blackBGImage.Dispose();
                }
                if (white2BGImage != null)
                {
                    white2BGImage.Dispose();
                }
            }

            if (windowImage != null)
            {
                Rectangle windowRectCropped = GraphicsMgr.GetCroppedArea((Bitmap)windowImage);
                windowImage = GraphicsMgr.CropImage(windowImage, windowRectCropped);

                if (Engine.conf.ShowCursor)
                {
                    windowRect.X += windowRectCropped.X;
                    windowRect.Y += windowRectCropped.Y;
                    DrawCursor(windowImage, windowRect.Location);
                }

                if (Engine.conf.ActiveWindowShowCheckers)
                {
                    windowImage = ImageEffects.DrawCheckers(windowImage);
                }
            }

            return(windowImage);
        }