/// <summary> /// Create a new bitmap where the sourceBitmap has a shadow /// </summary> /// <param name="sourceBitmap">Bitmap to make a shadow on</param> /// <param name="darkness">How dark is the shadow</param> /// <param name="shadowSize">Size of the shadow</param> /// <param name="targetPixelformat">What pixel format must the returning bitmap have</param> /// <param name="shadowOffset"></param> /// <param name="matrix"> /// The transform matrix which describes how the elements need to be transformed to stay at the same /// location /// </param> /// <returns>Bitmap with the shadow, is bigger than the sourceBitmap!!</returns> public static Bitmap CreateShadow(this Image sourceBitmap, float darkness, int shadowSize, NativePoint shadowOffset, Matrix matrix, PixelFormat targetPixelformat) { var offset = shadowOffset.Offset(shadowSize - 1, shadowSize - 1); matrix.Translate(offset.X, offset.Y, MatrixOrder.Append); // Create a new "clean" image var returnImage = BitmapFactory.CreateEmpty(sourceBitmap.Width + shadowSize * 2, sourceBitmap.Height + shadowSize * 2, targetPixelformat, Color.Empty, sourceBitmap.HorizontalResolution, sourceBitmap.VerticalResolution); // Make sure the shadow is odd, there is no reason for an even blur! if ((shadowSize & 1) == 0) { shadowSize++; } // Create "mask" for the shadow var maskMatrix = new ColorMatrix { Matrix00 = 0, Matrix11 = 0, Matrix22 = 0, Matrix33 = darkness }; var shadowRectangle = new NativeRect(new NativePoint(shadowSize, shadowSize), sourceBitmap.Size); ApplyColorMatrix((Bitmap)sourceBitmap, NativeRect.Empty, returnImage, shadowRectangle, maskMatrix); // blur "shadow", apply to whole new image // try normal software blur returnImage.ApplyBoxBlur(shadowSize); // Draw the original image over the shadow using (var graphics = Graphics.FromImage(returnImage)) { // Make sure we draw with the best quality! graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; // draw original with a TextureBrush so we have nice antialiasing! using (Brush textureBrush = new TextureBrush(sourceBitmap, WrapMode.Clamp)) { // We need to do a translate-transform otherwise the image is wrapped graphics.TranslateTransform(offset.X, offset.Y); graphics.FillRectangle(textureBrush, 0, 0, sourceBitmap.Width, sourceBitmap.Height); } } return(returnImage); }
/// <summary> /// Overriding the HandleMouseMove will help us to make sure the tail is always visible. /// Should fix BUG-1682 /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns>base.HandleMouseMove</returns> public override bool HandleMouseMove(int x, int y) { var returnValue = base.HandleMouseMove(x, y); var leftAligned = _boundsAfterResize.Right - _boundsAfterResize.Left >= 0; var topAligned = _boundsAfterResize.Bottom - _boundsAfterResize.Top >= 0; var xOffset = leftAligned ? -20 : 20; var yOffset = topAligned ? -20 : 20; var newGripperLocation = _initialGripperPoint.Offset(xOffset, yOffset); if (TargetAdorner.Location != newGripperLocation) { Invalidate(); TargetAdorner.Location = newGripperLocation; Invalidate(); } return(returnValue); }
/// <summary> /// Converts locationRelativeToScreenOrigin to be relative to top left corner of all screen bounds, which might /// be different in multiscreen setups. This implementation /// can conveniently be used when the cursor location is needed to deal with a fullscreen bitmap. /// </summary> /// <param name="locationRelativeToScreenOrigin"></param> /// <returns></returns> public static NativePoint GetLocationRelativeToScreenBounds(NativePoint locationRelativeToScreenOrigin) { var bounds = GetScreenBounds(); return(locationRelativeToScreenOrigin.Offset(-bounds.X, -bounds.Y)); }
/// <summary> /// This method takes the actual capture of the document (frame) /// </summary> /// <param name="documentContainer">DocumentContainer</param> /// <param name="contentWindowDetails">Needed for referencing the location of the frame</param> /// <param name="graphicsTarget">Graphics</param> /// <returns>Bitmap with the capture</returns> private static void DrawDocument(DocumentContainer documentContainer, IInteropWindow contentWindowDetails, Graphics graphicsTarget) { documentContainer.SetAttribute("scroll", 1); //Get Browser Window Width & Height var pageWidth = documentContainer.ScrollWidth; var pageHeight = documentContainer.ScrollHeight; if (pageWidth * pageHeight == 0) { Log.Warn().WriteLine("Empty page for DocumentContainer {0}: {1}", documentContainer.Name, documentContainer.Url); return; } //Get Screen Width & Height (this is better as the WindowDetails.ClientRectangle as the real visible parts are there! var viewportWidth = documentContainer.ClientWidth; var viewportHeight = documentContainer.ClientHeight; if (viewportWidth * viewportHeight == 0) { Log.Warn().WriteLine("Empty viewport for DocumentContainer {0}: {1}", documentContainer.Name, documentContainer.Url); return; } // Store the current location so we can set the browser back and use it for the mouse cursor var startLeft = documentContainer.ScrollLeft; var startTop = documentContainer.ScrollTop; Log.Debug().WriteLine("Capturing {4} with total size {0},{1} displayed with size {2},{3}", pageWidth, pageHeight, viewportWidth, viewportHeight, documentContainer.Name); // Variable used for looping horizontally var horizontalPage = 0; // The location of the browser, used as the destination into the bitmap target var targetOffset = new NativePoint(); // Loop of the pages and make a copy of the visible viewport while (horizontalPage * viewportWidth < pageWidth) { // Scroll to location documentContainer.ScrollLeft = viewportWidth * horizontalPage; targetOffset = targetOffset.ChangeX(documentContainer.ScrollLeft); // Variable used for looping vertically var verticalPage = 0; while (verticalPage * viewportHeight < pageHeight) { // Scroll to location documentContainer.ScrollTop = viewportHeight * verticalPage; //Shoot visible window targetOffset = targetOffset.ChangeY(documentContainer.ScrollTop); // Draw the captured fragment to the target, but "crop" the scrollbars etc while capturing var viewPortSize = new Size(viewportWidth, viewportHeight); var clientRectangle = new NativeRect(documentContainer.SourceLocation, viewPortSize); var fragment = contentWindowDetails.PrintWindow(); if (fragment != null) { Log.Debug().WriteLine("Captured fragment size: {0}x{1}", fragment.Width, fragment.Height); try { // cut all junk, due to IE "border" we need to remove some parts var viewportRect = documentContainer.ViewportRectangle; if (!viewportRect.IsEmpty) { Log.Debug().WriteLine("Cropping to viewport: {0}", viewportRect); BitmapHelper.Crop(ref fragment, ref viewportRect); } Log.Debug().WriteLine("Cropping to clientRectangle: {0}", clientRectangle); // Crop to clientRectangle if (BitmapHelper.Crop(ref fragment, ref clientRectangle)) { var targetLocation = new NativePoint(documentContainer.DestinationLocation.X, documentContainer.DestinationLocation.Y); Log.Debug().WriteLine("Fragment targetLocation is {0}", targetLocation); targetLocation = targetLocation.Offset(targetOffset); Log.Debug().WriteLine("After offsetting the fragment targetLocation is {0}", targetLocation); Log.Debug().WriteLine("Drawing fragment of size {0} to {1}", fragment.Size, targetLocation); graphicsTarget.DrawImage(fragment, targetLocation); graphicsTarget.Flush(); } else { // somehow we are capturing nothing!? Log.Warn().WriteLine("Crop of {0} failed?", documentContainer.Name); break; } } finally { fragment.Dispose(); } } else { Log.Warn().WriteLine("Capture of {0} failed!", documentContainer.Name); } verticalPage++; } horizontalPage++; } // Return to where we were documentContainer.ScrollLeft = startLeft; documentContainer.ScrollTop = startTop; }