public Image GenerateImage(string imageKey, string topText, string bottomText) { var img = _imageProvider.GetImage(imageKey); if (img == null) { return(null); } using (var g = Graphics.FromImage(img)) { g.SmoothingMode = SmoothingMode.AntiAlias; g.InterpolationMode = InterpolationMode.HighQualityBicubic; g.PixelOffsetMode = PixelOffsetMode.HighQuality; g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; var topRectangle = new RectangleF(0, 0, img.Width, img.Height / 2); var bottomRectangle = new RectangleF(0, img.Height / 2, img.Width, img.Height / 2); var upperTopText = topText.ToUpper(); var upperBottomText = bottomText.ToUpper(); var topSize = CalculateOptimumFontSize(img, topRectangle, TopFormat, upperTopText); var btmSize = CalculateOptimumFontSize(img, bottomRectangle, BtmFormat, upperBottomText); var path = new GraphicsPath(); path.AddString(upperTopText, FontFamily.GenericSansSerif, (int)FontStyle.Bold, topSize, topRectangle, TopFormat); path.AddString(upperBottomText, FontFamily.GenericSansSerif, (int)FontStyle.Bold, btmSize, bottomRectangle, BtmFormat); g.DrawPath(Pens.Black, path); g.FillPath(Brushes.White, path); g.Flush(); } return(img); }
public Image CreateImage( String src, IDictionary<String, String> attrs, ChainedProperties chain, IDocListener document, IImageProvider img_provider, Dictionary<String, Image> img_store, String img_baseurl) { Image img = null; // getting the image using an image provider if (img_provider != null) img = img_provider.GetImage(src, attrs, chain, document); // getting the image from an image store if (img == null && img_store != null) { Image tim; img_store.TryGetValue(src, out tim); if (tim != null) img = Image.GetInstance(tim); } if (img != null) return img; // introducing a base url // relative src references only if (!src.StartsWith("http") && img_baseurl != null) { src = img_baseurl + src; } else if (img == null && !src.StartsWith("http")) { String path = chain[HtmlTags.IMAGEPATH]; if (path == null) path = ""; src = Path.Combine(path, src); } img = Image.GetInstance(src); if (img == null) return null; float actualFontSize = HtmlUtilities.ParseLength( chain[HtmlTags.SIZE], HtmlUtilities.DEFAULT_FONT_SIZE); if (actualFontSize <= 0f) actualFontSize = HtmlUtilities.DEFAULT_FONT_SIZE; String width; attrs.TryGetValue(HtmlTags.WIDTH, out width); float widthInPoints = HtmlUtilities.ParseLength(width, actualFontSize); String height; attrs.TryGetValue(HtmlTags.HEIGHT, out height); float heightInPoints = HtmlUtilities.ParseLength(height, actualFontSize); if (widthInPoints > 0 && heightInPoints > 0) { img.ScaleAbsolute(widthInPoints, heightInPoints); } else if (widthInPoints > 0) { heightInPoints = img.Height * widthInPoints / img.Width; img.ScaleAbsolute(widthInPoints, heightInPoints); } else if (heightInPoints > 0) { widthInPoints = img.Width * heightInPoints / img.Height; img.ScaleAbsolute(widthInPoints, heightInPoints); } String before = chain[HtmlTags.BEFORE]; if (before != null) img.SpacingBefore = float.Parse(before, CultureInfo.InvariantCulture); String after = chain[HtmlTags.AFTER]; if (after != null) img.SpacingAfter = float.Parse(after, CultureInfo.InvariantCulture); img.WidthPercentage = 0; return img; }
public virtual void StartElement(String tag, Hashtable h) { if (!tagsSupported.ContainsKey(tag)) { return; } style.ApplyStyle(tag, h); String follow = (String)FactoryProperties.followTags[tag]; if (follow != null) { Hashtable prop = new Hashtable(); prop[follow] = null; cprops.AddToChain(follow, prop); return; } FactoryProperties.InsertStyle(h, cprops); if (tag.Equals(HtmlTags.ANCHOR)) { cprops.AddToChain(tag, h); if (currentParagraph == null) { currentParagraph = new Paragraph(); } stack.Push(currentParagraph); currentParagraph = new Paragraph(); return; } if (tag.Equals(HtmlTags.NEWLINE)) { if (currentParagraph == null) { currentParagraph = new Paragraph(); } currentParagraph.Add(factoryProperties.CreateChunk("\n", cprops)); return; } if (tag.Equals(HtmlTags.HORIZONTALRULE)) { // Attempting to duplicate the behavior seen on Firefox with // http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_hr_test // where an initial break is only inserted when the preceding element doesn't // end with a break, but a trailing break is always inserted. bool addLeadingBreak = true; if (currentParagraph == null) { currentParagraph = new Paragraph(); addLeadingBreak = false; } if (addLeadingBreak) // Not a new paragraph { int numChunks = currentParagraph.Chunks.Count; if (numChunks == 0 || ((Chunk)currentParagraph.Chunks[numChunks - 1]).Content.EndsWith("\n")) { addLeadingBreak = false; } } String align = (String)h["align"]; int hrAlign = Element.ALIGN_CENTER; if (align != null) { if (Util.EqualsIgnoreCase(align, "left")) { hrAlign = Element.ALIGN_LEFT; } if (Util.EqualsIgnoreCase(align, "right")) { hrAlign = Element.ALIGN_RIGHT; } } String width = (String)h["width"]; float hrWidth = 1; if (width != null) { float tmpWidth = Markup.ParseLength(width, Markup.DEFAULT_FONT_SIZE); if (tmpWidth > 0) { hrWidth = tmpWidth; } if (!width.EndsWith("%")) { hrWidth = 100; // Treat a pixel width as 100% for now. } } String size = (String)h["size"]; float hrSize = 1; if (size != null) { float tmpSize = Markup.ParseLength(size, Markup.DEFAULT_FONT_SIZE); if (tmpSize > 0) { hrSize = tmpSize; } } if (addLeadingBreak) { currentParagraph.Add(Chunk.NEWLINE); } currentParagraph.Add(new LineSeparator(hrSize, hrWidth, null, hrAlign, currentParagraph.Leading / 2)); currentParagraph.Add(Chunk.NEWLINE); return; } if (tag.Equals(HtmlTags.CHUNK) || tag.Equals(HtmlTags.SPAN)) { cprops.AddToChain(tag, h); return; } if (tag.Equals(HtmlTags.IMAGE)) { String src = (String)h[ElementTags.SRC]; if (src == null) { return; } cprops.AddToChain(tag, h); Image img = null; if (interfaceProps != null) { IImageProvider ip = (IImageProvider)interfaceProps["img_provider"]; if (ip != null) { img = ip.GetImage(src, h, cprops, document); } if (img == null) { Hashtable images = (Hashtable)interfaceProps["img_static"]; if (images != null) { Image tim = (Image)images[src]; if (tim != null) { img = Image.GetInstance(tim); } } else { if (!src.StartsWith("http")) // relative src references only { String baseurl = (String)interfaceProps["img_baseurl"]; if (baseurl != null) { src = baseurl + src; img = Image.GetInstance(src); } } } } } if (img == null) { if (!src.StartsWith("http")) { String path = cprops["image_path"]; if (path == null) { path = ""; } src = Path.Combine(path, src); } img = Image.GetInstance(src); } String align = (String)h["align"]; String width = (String)h["width"]; String height = (String)h["height"]; String before = cprops["before"]; String after = cprops["after"]; if (before != null) { img.SpacingBefore = float.Parse(before, System.Globalization.NumberFormatInfo.InvariantInfo); } if (after != null) { img.SpacingAfter = float.Parse(after, System.Globalization.NumberFormatInfo.InvariantInfo); } float actualFontSize = Markup.ParseLength(cprops[ElementTags.SIZE], Markup.DEFAULT_FONT_SIZE); if (actualFontSize <= 0f) { actualFontSize = Markup.DEFAULT_FONT_SIZE; } float widthInPoints = Markup.ParseLength(width, actualFontSize); float heightInPoints = Markup.ParseLength(height, actualFontSize); if (widthInPoints > 0 && heightInPoints > 0) { img.ScaleAbsolute(widthInPoints, heightInPoints); } else if (widthInPoints > 0) { heightInPoints = img.Height * widthInPoints / img.Width; img.ScaleAbsolute(widthInPoints, heightInPoints); } else if (heightInPoints > 0) { widthInPoints = img.Width * heightInPoints / img.Height; img.ScaleAbsolute(widthInPoints, heightInPoints); } img.WidthPercentage = 0; if (align != null) { EndElement("p"); int ralign = Image.MIDDLE_ALIGN; if (Util.EqualsIgnoreCase(align, "left")) { ralign = Image.LEFT_ALIGN; } else if (Util.EqualsIgnoreCase(align, "right")) { ralign = Image.RIGHT_ALIGN; } img.Alignment = ralign; IImg i = null; bool skip = false; if (interfaceProps != null) { i = (IImg)interfaceProps["img_interface"]; if (i != null) { skip = i.Process(img, h, cprops, document); } } if (!skip) { document.Add(img); } cprops.RemoveChain(tag); } else { cprops.RemoveChain(tag); if (currentParagraph == null) { currentParagraph = FactoryProperties.CreateParagraph(cprops); } currentParagraph.Add(new Chunk(img, 0, 0)); } return; } EndElement("p"); if (tag.Equals("h1") || tag.Equals("h2") || tag.Equals("h3") || tag.Equals("h4") || tag.Equals("h5") || tag.Equals("h6")) { if (!h.ContainsKey(ElementTags.SIZE)) { int v = 7 - int.Parse(tag.Substring(1)); h[ElementTags.SIZE] = v.ToString(); } cprops.AddToChain(tag, h); return; } if (tag.Equals(HtmlTags.UNORDEREDLIST)) { if (pendingLI) { EndElement(HtmlTags.LISTITEM); } skipText = true; cprops.AddToChain(tag, h); List list = new List(false); try{ list.IndentationLeft = float.Parse(cprops["indent"], System.Globalization.NumberFormatInfo.InvariantInfo); }catch { list.Autoindent = true; } list.SetListSymbol("\u2022"); stack.Push(list); return; } if (tag.Equals(HtmlTags.ORDEREDLIST)) { if (pendingLI) { EndElement(HtmlTags.LISTITEM); } skipText = true; cprops.AddToChain(tag, h); List list = new List(true); try{ list.IndentationLeft = float.Parse(cprops["indent"], System.Globalization.NumberFormatInfo.InvariantInfo); }catch { list.Autoindent = true; } stack.Push(list); return; } if (tag.Equals(HtmlTags.LISTITEM)) { if (pendingLI) { EndElement(HtmlTags.LISTITEM); } skipText = false; pendingLI = true; cprops.AddToChain(tag, h); stack.Push(FactoryProperties.CreateListItem(cprops)); return; } if (tag.Equals(HtmlTags.DIV) || tag.Equals(HtmlTags.BODY) || tag.Equals("p")) { cprops.AddToChain(tag, h); return; } if (tag.Equals(HtmlTags.PRE)) { if (!h.ContainsKey(ElementTags.FACE)) { h[ElementTags.FACE] = "Courier"; } cprops.AddToChain(tag, h); isPRE = true; return; } if (tag.Equals("tr")) { if (pendingTR) { EndElement("tr"); } skipText = true; pendingTR = true; cprops.AddToChain("tr", h); return; } if (tag.Equals("td") || tag.Equals("th")) { if (pendingTD) { EndElement(tag); } skipText = false; pendingTD = true; cprops.AddToChain("td", h); stack.Push(new IncCell(tag, cprops)); return; } if (tag.Equals("table")) { cprops.AddToChain("table", h); IncTable table = new IncTable(h); stack.Push(table); tableState.Push(new bool[] { pendingTR, pendingTD }); pendingTR = pendingTD = false; skipText = true; return; } }
virtual public Image CreateImage( String src, IDictionary <String, String> attrs, ChainedProperties chain, IDocListener document, IImageProvider img_provider, Dictionary <String, Image> img_store, String img_baseurl) { Image img = null; // getting the image using an image provider if (img_provider != null) { img = img_provider.GetImage(src, attrs, chain, document); } // getting the image from an image store if (img == null && img_store != null) { Image tim; img_store.TryGetValue(src, out tim); if (tim != null) { img = Image.GetInstance(tim); } } if (img != null) { return(img); } // introducing a base url // relative src references only if (!src.StartsWith("http") && img_baseurl != null) { src = img_baseurl + src; } else if (img == null && !src.StartsWith("http")) { String path = chain[HtmlTags.IMAGEPATH]; if (path == null) { path = ""; } src = Path.Combine(path, src); } img = Image.GetInstance(src); if (img == null) { return(null); } float actualFontSize = HtmlUtilities.ParseLength( chain[HtmlTags.SIZE], HtmlUtilities.DEFAULT_FONT_SIZE); if (actualFontSize <= 0f) { actualFontSize = HtmlUtilities.DEFAULT_FONT_SIZE; } String width; attrs.TryGetValue(HtmlTags.WIDTH, out width); float widthInPoints = HtmlUtilities.ParseLength(width, actualFontSize); String height; attrs.TryGetValue(HtmlTags.HEIGHT, out height); float heightInPoints = HtmlUtilities.ParseLength(height, actualFontSize); if (widthInPoints > 0 && heightInPoints > 0) { img.ScaleAbsolute(widthInPoints, heightInPoints); } else if (widthInPoints > 0) { heightInPoints = img.Height * widthInPoints / img.Width; img.ScaleAbsolute(widthInPoints, heightInPoints); } else if (heightInPoints > 0) { widthInPoints = img.Width * heightInPoints / img.Height; img.ScaleAbsolute(widthInPoints, heightInPoints); } String before = chain[HtmlTags.BEFORE]; if (before != null) { img.SpacingBefore = float.Parse(before, CultureInfo.InvariantCulture); } String after = chain[HtmlTags.AFTER]; if (after != null) { img.SpacingAfter = float.Parse(after, CultureInfo.InvariantCulture); } img.WidthPercentage = 0; return(img); }
/// <summary> /// Encapsulates an algorithm for creating full-page images of a page. /// </summary> /// <param name="positionProvider">The position provider used for moving to the actual stitch points.</param> /// <param name="region">The region to stitch. If <see cref="Region.Empty"/>, the entire image will be stitched.</param> /// <param name="fullarea">The wanted area of the resulting image. If unknown, pass in <c>null</c> or <see cref="Region.Empty"/>.</param> /// <param name="originProvider">A position provider used for saving the state before /// starting the stitching, as well as moving to (0,0). The reason it is separated from /// the <c>stitchProvider</c>is that the stitchProvider might have side-effects /// (e.g., changing the CSS transform of the page can cause a layout change at the /// top of the page), which we can avoid for the first screenshot (since it might be a /// full page screenshot anyway).</param> /// <param name="stitchOffset"></param> /// <returns>The screenshot as Bitmap.</returns> public Bitmap GetStitchedRegion(Region region, Region fullarea, IPositionProvider positionProvider, IPositionProvider originProvider, Size stitchOffset) { ArgumentGuard.NotNull(region, nameof(region)); ArgumentGuard.NotNull(positionProvider, nameof(positionProvider)); logger_.Verbose("region: {0} ; fullarea: {1} ; positionProvider: {2}", region, fullarea, positionProvider.GetType().Name); Point originalStitchedState = positionProvider.GetCurrentPosition(); logger_.Verbose("region size: {0}, originalStitchedState: {1}", region, originalStitchedState); PositionMemento originProviderState = originProvider.GetState(); logger_.Verbose("originProviderState: {0}", originProviderState); originProvider.SetPosition(Point.Empty); Thread.Sleep(waitBeforeScreenshots_); Bitmap initialScreenshot = imageProvider_.GetImage(); Size initialPhysicalSize = initialScreenshot.Size; SaveDebugScreenshotPart_(initialScreenshot, region.ToRectangle(), "initial"); IScaleProvider scaleProvider = scaleProviderFactory_.GetScaleProvider(initialScreenshot.Width); double pixelRatio = 1 / scaleProvider.ScaleRatio; Size initialSizeScaled = new Size((int)Math.Round(initialScreenshot.Width / pixelRatio), (int)Math.Round(initialScreenshot.Height / pixelRatio)); ICutProvider scaledCutProvider = cutProvider_.Scale(pixelRatio); if (pixelRatio != 1 && !(scaledCutProvider is NullCutProvider)) { initialScreenshot = cutProvider_.Cut(initialScreenshot); debugScreenshotsProvider_.Save(initialScreenshot, "original-cut"); } Region regionInScreenshot = GetRegionInScreenshot_(region, initialScreenshot, pixelRatio); Bitmap croppedInitialScreenshot = CropScreenshot_(initialScreenshot, regionInScreenshot); debugScreenshotsProvider_.Save(croppedInitialScreenshot, "cropped"); Bitmap scaledInitialScreenshot = BasicImageUtils.ScaleImage(croppedInitialScreenshot, scaleProvider); if (!object.ReferenceEquals(scaledInitialScreenshot, croppedInitialScreenshot)) { SaveDebugScreenshotPart_(scaledInitialScreenshot, regionInScreenshot.ToRectangle(), "scaled"); } if (fullarea.IsEmpty) { Size entireSize; try { entireSize = positionProvider.GetEntireSize(); logger_.Verbose("Entire size of region context: {0}", entireSize); } catch (EyesException e) { logger_.Log("WARNING: Failed to extract entire size of region context" + e.Message); logger_.Log("Using image size instead: " + scaledInitialScreenshot.Width + "x" + scaledInitialScreenshot.Height); entireSize = new Size(scaledInitialScreenshot.Width, scaledInitialScreenshot.Height); } // Notice that this might still happen even if we used // "getImagePart", since "entirePageSize" might be that of a frame. if (scaledInitialScreenshot.Width >= entireSize.Width && scaledInitialScreenshot.Height >= entireSize.Height) { logger_.Log("WARNING: Seems the image is already a full page screenshot."); if (!object.ReferenceEquals(scaledInitialScreenshot, initialScreenshot)) { initialScreenshot.Dispose(); } return(scaledInitialScreenshot); } fullarea = new Region(Point.Empty, entireSize, CoordinatesTypeEnum.SCREENSHOT_AS_IS); } float currentFullWidth = fullarea.Width; fullarea = sizeAdjuster_.AdjustRegion(fullarea, initialSizeScaled); float sizeRatio = currentFullWidth / fullarea.Width; logger_.Verbose("adjusted fullarea: {0}", fullarea); Point scaledCropLocation = fullarea.Location; Point physicalCropLocation = new Point( (int)Math.Ceiling(scaledCropLocation.X * pixelRatio), (int)Math.Ceiling(scaledCropLocation.Y * pixelRatio)); Rectangle sourceRegion; if (regionInScreenshot.IsSizeEmpty) { Size physicalCropSize = new Size(initialPhysicalSize.Width - physicalCropLocation.X, initialPhysicalSize.Height - physicalCropLocation.Y); sourceRegion = new Rectangle(physicalCropLocation, physicalCropSize); } else { // Starting with the screenshot we already captured at (0,0). sourceRegion = regionInScreenshot.ToRectangle(); } Rectangle scaledCroppedSourceRect = cutProvider_.ToRectangle(sourceRegion.Size); scaledCroppedSourceRect.Offset(sourceRegion.Location); Rectangle scaledCroppedSourceRegion = new Rectangle( (int)Math.Ceiling(scaledCroppedSourceRect.X / pixelRatio), (int)Math.Ceiling(scaledCroppedSourceRect.Y / pixelRatio), (int)Math.Ceiling(scaledCroppedSourceRect.Width / pixelRatio), (int)Math.Ceiling(scaledCroppedSourceRect.Height / pixelRatio)); Size scaledCropSize = scaledCroppedSourceRegion.Size; // The screenshot part is a bit smaller than the screenshot size, in order to eliminate // duplicate bottom/right-side scroll bars, as well as fixed position footers. Size screenshotPartSize = new Size( Math.Max(scaledCropSize.Width, MinScreenshotPartSize_), Math.Max(scaledCropSize.Height, MinScreenshotPartSize_) ); logger_.Verbose("Screenshot part size: {0}", screenshotPartSize); // Getting the list of viewport regions composing the page (we'll take screenshot for each one). Rectangle rectInScreenshot; if (regionInScreenshot.IsSizeEmpty) { int x = Math.Max(0, fullarea.Left); int y = Math.Max(0, fullarea.Top); int w = Math.Min(fullarea.Width, scaledCropSize.Width); int h = Math.Min(fullarea.Height, scaledCropSize.Height); rectInScreenshot = new Rectangle( (int)Math.Round(x * pixelRatio), (int)Math.Round(y * pixelRatio), (int)Math.Round(w * pixelRatio), (int)Math.Round(h * pixelRatio)); } else { rectInScreenshot = regionInScreenshot.Rectangle; } fullarea = CoerceImageSize_(fullarea); ICollection <SubregionForStitching> screenshotParts = fullarea.GetSubRegions(screenshotPartSize, stitchOverlap_, pixelRatio, rectInScreenshot, logger_); Bitmap stitchedImage = new Bitmap(fullarea.Width, fullarea.Height); // Take screenshot and stitch for each screenshot part. StitchScreenshot_(stitchOffset, positionProvider, screenshotParts, stitchedImage, scaleProvider.ScaleRatio, scaledCutProvider, sizeRatio); positionProvider.SetPosition(originalStitchedState); originProvider.RestoreState(originProviderState); croppedInitialScreenshot.Dispose(); return(stitchedImage); }
/// <summary> /// Forces all images sizes to be refreshed from the respective providers. /// </summary> protected void RefreshItemImages() { Size imageSize = IconImageProvider.GetIconSize(ImageSize); ImageScalingSize = imageSize; bool changesMade = false; IImageProvider imageProvider = null; SuspendLayout(); foreach (ToolStripItem item in Items) { if (item.Size != imageSize) { imageProvider = null; // If an image provider was registered with the toolstrip then... if (ContainsImage(item)) { if (IsImageSupported(item, ImageSize)) { item.Image = GetImage(item, ImageSize); } else if (UseUnknownImageSizeIcon && IsImageSupported(ImageSize)) { item.Image = GetImage(ImageSize); } changesMade = true; } else if (item is IImageProvider) { imageProvider = item as IImageProvider; } else if (item.Tag is IImageProvider) { imageProvider = item.Tag as IImageProvider; } // If an alternative image provider was found, attempt to use that. if (!changesMade && imageProvider != null) { if (imageProvider.IsImageSupported(ImageSize)) { item.Image = imageProvider.GetImage(ImageSize); changesMade = true; } } // Were changes made? if (changesMade) { // Automatically adjust the image scaling mode. if (item.Image != null && item.Image.Size == imageSize) { item.ImageScaling = ToolStripItemImageScaling.None; } else { item.ImageScaling = ToolStripItemImageScaling.SizeToFit; } } } } ResumeLayout(); }
public async Task <CreateImageFromImageResult> CreateImageFromExistingImage(FolderIdType folderId, FileIdType fileId, FileIdType newFileId, int quality, int width, bool asProgressive = true) { var fileName = $"{_prefix}/{folderId}/{fileId}"; var newFileName = $"{_prefix}/{folderId}/{newFileId}"; var newGetRequest = new GetObjectMetadataRequest { BucketName = _bucketName, Key = newFileName }; try { var newGetResponse = await _client.GetObjectMetadataAsync(newGetRequest); var newUri = GetUri(fileName); throw new Exception($"The blob you want to create already exists - {newUri}!"); } catch (AmazonS3Exception ex) { if (ex.ErrorCode == "NotFound") { var oldGetRequest = new GetObjectRequest { BucketName = _bucketName, Key = fileName }; var oldRequest = await _client.GetObjectAsync(oldGetRequest); var oldUri = GetUri(fileName); if (oldRequest.HttpStatusCode == System.Net.HttpStatusCode.OK) { byte[] bytes; using (var ms = new MemoryStream()) { await oldRequest.ResponseStream.CopyToAsync(ms); ms.Position = 0; bytes = ms.ToArray(); } var imageResult = await _imageService.GetImage(bytes, width, quality, asProgressive); var uri = await Upload(folderId, newFileId, imageResult.Bytes, oldRequest.Headers.ContentType); var thumbNailImageResult = await _imageService.GetImage(bytes, 250, 60, true); var thumbnailUri = await Upload(folderId, newFileId, thumbNailImageResult.Bytes, oldRequest.Headers.ContentType, true); return(new CreateImageFromImageResult { ImageProcessResult = imageResult, Uri = uri, ThumbnailUri = thumbnailUri }); } else { throw new Exception($"The blob you want to copy doesn't exists - {oldUri}!"); } } else { throw; } } }
private void LoadFromDisk(string fileName) { _realImage = _imageProvider.GetImage(fileName); }