private Image GetImage(RectangleF bounds) { _patternElement.PatternBounds = new SvgRect(bounds.X, bounds.Y, bounds.Width, bounds.Height); // For single image pattern... if (_patternElement.ChildNodes.Count == 1) { var imageElement = _patternElement.ChildNodes[0] as SvgImageElement; if (imageElement != null) { var image = GdiImageRendering.GetBitmap(imageElement); if (image != null) { return(image); } } } GdiGraphicsRenderer renderer = new GdiGraphicsRenderer(true, false); var svgWindow = _patternElement.OwnerDocument.Window as SvgWindow; var ownedWindow = svgWindow.CreateOwnedWindow(); renderer.Window = ownedWindow; SvgSvgElement elm = MoveIntoSvgElement(); int winWidth = (int)elm.Width.BaseVal.Value; int winHeight = (int)elm.Height.BaseVal.Value; if (winWidth == 0 || winHeight == 0) { var size = elm.GetSize(); if (size.Width.Equals(0) || size.Height.Equals(0)) { winWidth = (int)bounds.Width; winHeight = (int)bounds.Height; } else { winWidth = (int)size.Width; winHeight = (int)size.Height; } } ownedWindow.Resize(winWidth, winHeight); renderer.Render(elm as SvgElement); Image img = renderer.RasterImage; MoveOutOfSvgElement(elm); return(img); }
private void InvalidateAndRender() { try { if (_svgRenderer != null) { SvgSvgElement svgEl = (SvgSvgElement)_svgWindow.Document.RootElement; SvgSizeF r = svgEl.GetSize(); int winWidth = (int)svgEl.Width.BaseVal.Value; int winHeight = (int)svgEl.Height.BaseVal.Value; if (!r.Width.Equals(0.0) && !r.Height.Equals(0.0) && (r.Width * 4 * r.Height) < BitmapLimit) { winWidth = (int)r.Width; winHeight = (int)r.Height; } if ((winWidth * 4 * winHeight) >= BitmapLimit) { winWidth = this.Width; winHeight = this.Height; } _svgWindow.Resize(winWidth, winHeight); _svgRenderer.Render(_svgWindow.Document as SvgDocument); } } catch (Exception ex) { Trace.TraceError(ex.ToString()); if (this.DesignMode) { return; } var errorArgs = new SvgErrorArgs("An exception occurred while rendering", ex); _svgErrors?.Invoke(this, errorArgs); if (!errorArgs.Handled) { MessageBox.Show(errorArgs.Message + ": " + ex.Message, _appTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
protected virtual void Load() { try { if (!string.IsNullOrWhiteSpace(_svgSource)) { // Load the source _svgWindow.Source = _svgSource; // Initialize the style sheets SetupStyleSheets(); // Execute all script elements //UnloadEngines(); //InitializeEvents(); //ExecuteScripts(); SvgSvgElement svgEl = (SvgSvgElement)_svgWindow.Document.RootElement; SvgSizeF r = svgEl.GetSize(); int winWidth = (int)svgEl.Width.BaseVal.Value; int winHeight = (int)svgEl.Height.BaseVal.Value; if (!r.Width.Equals(0.0) && !r.Height.Equals(0.0) && (r.Width * 4 * r.Height) < BitmapLimit) { winWidth = (int)r.Width; winHeight = (int)r.Height; } if ((winWidth * 4 * winHeight) >= BitmapLimit) { winWidth = this.Width; winHeight = this.Height; } _svgWindow.Resize(winWidth, winHeight); _svgRenderer.InvalidRect = SvgRectF.Empty; this.Render(); _isSvgLoaded = true; } else if (!string.IsNullOrWhiteSpace(_xmlSource) && _xmlSource.Length > ValidSVG.Length) { SvgDocument doc = _svgWindow.CreateEmptySvgDocument(); doc.LoadXml(_xmlSource); _svgWindow.Document = doc; SetupStyleSheets(); SvgSvgElement svgEl = (SvgSvgElement)_svgWindow.Document.RootElement; SvgSizeF r = svgEl.GetSize(); int winWidth = (int)svgEl.Width.BaseVal.Value; int winHeight = (int)svgEl.Height.BaseVal.Value; if (!r.Width.Equals(0.0) && !r.Height.Equals(0.0) && (r.Width * 4 * r.Height) < BitmapLimit) { winWidth = (int)r.Width; winHeight = (int)r.Height; } if ((winWidth * 4 * winHeight) >= BitmapLimit) { winWidth = this.Width; winHeight = this.Height; } _svgWindow.Resize(winWidth, winHeight); _svgRenderer.InvalidRect = SvgRectF.Empty; this.Render(); _isSvgLoaded = true; } else if (_uriSource != null) { // Load the source _svgWindow.Source = _uriSource.AbsoluteUri; // Initialize the style sheets SetupStyleSheets(); // Execute all script elements //UnloadEngines(); //InitializeEvents(); //ExecuteScripts(); SvgSvgElement svgEl = (SvgSvgElement)_svgWindow.Document.RootElement; SvgSizeF r = svgEl.GetSize(); int winWidth = (int)svgEl.Width.BaseVal.Value; int winHeight = (int)svgEl.Height.BaseVal.Value; if (!r.Width.Equals(0.0) && !r.Height.Equals(0.0) && (r.Width * 4 * r.Height) < BitmapLimit) { winWidth = (int)r.Width; winHeight = (int)r.Height; } if ((winWidth * 4 * winHeight) >= BitmapLimit) { winWidth = this.Width; winHeight = this.Height; } _svgWindow.Resize(winWidth, winHeight); _svgRenderer.InvalidRect = SvgRectF.Empty; this.Render(); _isSvgLoaded = true; } else if (_streamSource != null) { SvgDocument doc = _svgWindow.CreateEmptySvgDocument(); doc.Load(_streamSource); _svgWindow.Document = doc; SetupStyleSheets(); SvgSvgElement svgEl = (SvgSvgElement)_svgWindow.Document.RootElement; SvgSizeF r = svgEl.GetSize(); int winWidth = (int)svgEl.Width.BaseVal.Value; int winHeight = (int)svgEl.Height.BaseVal.Value; if (!r.Width.Equals(0.0) && !r.Height.Equals(0.0) && (r.Width * 4 * r.Height) < BitmapLimit) { winWidth = (int)r.Width; winHeight = (int)r.Height; } if ((winWidth * 4 * winHeight) >= BitmapLimit) { winWidth = this.Width; winHeight = this.Height; } _svgWindow.Resize(winWidth, winHeight); _svgRenderer.InvalidRect = SvgRectF.Empty; this.Render(); _isSvgLoaded = true; } } catch (Exception ex) { Trace.TraceError(ex.ToString()); if (this.DesignMode) { return; } var errorArgs = new SvgErrorArgs("An error occurred while loading the document", ex); _svgErrors?.Invoke(this, errorArgs); if (!errorArgs.Handled) { MessageBox.Show(errorArgs.Message + ": " + ex.Message, _appTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
public override void Render(GdiGraphicsRenderer renderer) { base.Render(renderer); var graphics = renderer.GdiGraphics; SvgImageElement iElement = (SvgImageElement)_svgElement; ImageAttributes imageAttributes = new ImageAttributes(); float opacityValue = -1; string opacity = iElement.GetAttribute("opacity"); if (string.IsNullOrWhiteSpace(opacity)) { opacity = iElement.GetPropertyValue("opacity"); } if (!string.IsNullOrWhiteSpace(opacity)) { opacityValue = (float)SvgNumber.ParseNumber(opacity); opacityValue = Math.Min(opacityValue, 1); opacityValue = Math.Max(opacityValue, 0); } if (opacityValue >= 0 && opacityValue < 1) { ColorMatrix colorMatrix = new ColorMatrix(); colorMatrix.Matrix00 = 1.00f; // Red colorMatrix.Matrix11 = 1.00f; // Green colorMatrix.Matrix22 = 1.00f; // Blue colorMatrix.Matrix33 = opacityValue; // alpha colorMatrix.Matrix44 = 1.00f; // w imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); } float width = (float)iElement.Width.AnimVal.Value; float height = (float)iElement.Height.AnimVal.Value; RectangleF destRect = new RectangleF((float)iElement.X.AnimVal.Value, (float)iElement.Y.AnimVal.Value, (float)iElement.Width.AnimVal.Value, (float)iElement.Height.AnimVal.Value); RectangleF srcRect; RectangleF clipRect = destRect; // var container = graphics.BeginContainer(); graphics.SetClip(new Region(clipRect), CombineMode.Intersect); Image image = null; SvgWindow svgWnd = null; if (iElement.IsSvgImage) { svgWnd = GetSvgWindow(graphics); if (width > 0 && height > 0) { srcRect = new RectangleF(0, 0, width, height); } else { SvgSvgElement svgEl = (SvgSvgElement)svgWnd.Document.RootElement; SvgSizeF size = svgEl.GetSize(); srcRect = new RectangleF(new PointF(0, 0), new SizeF(size.Width, size.Height)); } } else { image = GetBitmap(iElement); if (image == null) { return; } srcRect = new RectangleF(0, 0, image.Width, image.Height); } ISvgAnimatedPreserveAspectRatio animatedAspectRatio = iElement.PreserveAspectRatio; if (animatedAspectRatio != null && animatedAspectRatio.AnimVal != null) { SvgPreserveAspectRatio aspectRatio = animatedAspectRatio.AnimVal as SvgPreserveAspectRatio; SvgPreserveAspectRatioType aspectRatioType = (aspectRatio != null) ? aspectRatio.Align : SvgPreserveAspectRatioType.Unknown; if (aspectRatio != null && aspectRatioType != SvgPreserveAspectRatioType.None && aspectRatioType != SvgPreserveAspectRatioType.Unknown) { var fScaleX = destRect.Width / srcRect.Width; var fScaleY = destRect.Height / srcRect.Height; var xOffset = 0.0f; var yOffset = 0.0f; SvgMeetOrSlice meetOrSlice = aspectRatio.MeetOrSlice; if (meetOrSlice == SvgMeetOrSlice.Slice) { fScaleX = Math.Max(fScaleX, fScaleY); fScaleY = Math.Max(fScaleX, fScaleY); } else { fScaleX = Math.Min(fScaleX, fScaleY); fScaleY = Math.Min(fScaleX, fScaleY); } switch (aspectRatioType) { case SvgPreserveAspectRatioType.XMinYMin: break; case SvgPreserveAspectRatioType.XMidYMin: xOffset = (destRect.Width - srcRect.Width * fScaleX) / 2; break; case SvgPreserveAspectRatioType.XMaxYMin: xOffset = (destRect.Width - srcRect.Width * fScaleX); break; case SvgPreserveAspectRatioType.XMinYMid: yOffset = (destRect.Height - srcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatioType.XMidYMid: xOffset = (destRect.Width - srcRect.Width * fScaleX) / 2; yOffset = (destRect.Height - srcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatioType.XMaxYMid: xOffset = (destRect.Width - srcRect.Width * fScaleX); yOffset = (destRect.Height - srcRect.Height * fScaleY) / 2; break; case SvgPreserveAspectRatioType.XMinYMax: yOffset = (destRect.Height - srcRect.Height * fScaleY); break; case SvgPreserveAspectRatioType.XMidYMax: xOffset = (destRect.Width - srcRect.Width * fScaleX) / 2; yOffset = (destRect.Height - srcRect.Height * fScaleY); break; case SvgPreserveAspectRatioType.XMaxYMax: xOffset = (destRect.Width - srcRect.Width * fScaleX); yOffset = (destRect.Height - srcRect.Height * fScaleY); break; } destRect = new RectangleF(destRect.X + xOffset, destRect.Y + yOffset, srcRect.Width * fScaleX, srcRect.Height * fScaleY); } if (image != null) { SvgColorProfileElement colorProfile = (SvgColorProfileElement)iElement.ColorProfile; if (colorProfile != null) { SvgUriReference svgUri = colorProfile.UriReference; Uri profileUri = new Uri(svgUri.AbsoluteUri); imageAttributes.SetOutputChannelColorProfile(profileUri.LocalPath, ColorAdjustType.Default); } graphics.DrawImage(this, image, destRect, srcRect, GraphicsUnit.Pixel, imageAttributes); image.Dispose(); image = null; } else if (iElement.IsSvgImage && svgWnd != null) { svgWnd.Resize((int)srcRect.Width, (int)srcRect.Height); var currOffset = new PointF(graphics.Transform.OffsetX, graphics.Transform.OffsetY); if (!currOffset.IsEmpty) { graphics.TranslateTransform(-currOffset.X, -currOffset.Y); } graphics.ScaleTransform(destRect.Width / srcRect.Width, destRect.Height / srcRect.Height); if (!currOffset.IsEmpty) { graphics.TranslateTransform(currOffset.X + destRect.X, currOffset.Y + destRect.Y); } _embeddedRenderer.Render(svgWnd.Document); } graphics.ResetClip(); // graphics.EndContainer(container); } if (_embeddedRenderer != null) { _embeddedRenderer.GdiGraphics = null; _embeddedRenderer.Dispose(); _embeddedRenderer = null; } if (imageAttributes != null) { imageAttributes.Dispose(); imageAttributes = null; } }
public static Image GetBitmap(SvgImageElement element) { var comparer = StringComparison.OrdinalIgnoreCase; if (!element.IsSvgImage) { if (!element.Href.AnimVal.StartsWith("data:", comparer)) { SvgUriReference svgUri = element.UriReference; Uri imageUri = new Uri(svgUri.AbsoluteUri); if (imageUri.IsFile && File.Exists(imageUri.LocalPath)) { return(Image.FromFile(imageUri.LocalPath, element.ColorProfile != null)); } WebResponse resource = svgUri.ReferencedResource; if (resource == null) { return(null); } Stream stream = resource.GetResponseStream(); if (stream == null) { return(null); } return(Image.FromStream(stream, element.ColorProfile != null)); } string sURI = element.Href.AnimVal.Replace(" ", "").Trim(); sURI = sURI.Replace(@"\n", ""); int nColon = sURI.IndexOf(":", comparer); int nSemiColon = sURI.IndexOf(";", comparer); int nComma = sURI.IndexOf(",", comparer); string sMimeType = sURI.Substring(nColon + 1, nSemiColon - nColon - 1); string sContent = sURI.Substring(nComma + 1); sContent = sContent.Replace('-', '+').Replace('_', '/'); sContent = sContent.PadRight(4 * ((sContent.Length + 3) / 4), '='); byte[] bResult = Convert.FromBase64CharArray(sContent.ToCharArray(), 0, sContent.Length); if (sMimeType.Equals("image/svg+xml", StringComparison.OrdinalIgnoreCase)) { GdiGraphicsRenderer renderer = new GdiGraphicsRenderer(true, false); var currentWindow = element.OwnerDocument.Window as SvgWindow; var svgWindow = currentWindow.CreateOwnedWindow(); renderer.Window = svgWindow; SvgDocument doc = svgWindow.CreateEmptySvgDocument(); bool isGZiped = sContent.StartsWith(GdiObject.GZipSignature, StringComparison.Ordinal); if (isGZiped) { byte[] imageBytes = Convert.FromBase64CharArray(sContent.ToCharArray(), 0, sContent.Length); using (var stream = new MemoryStream(imageBytes)) { using (GZipStream zipStream = new GZipStream(stream, CompressionMode.Decompress)) { doc.Load(zipStream); } } } else { var svgData = Convert.FromBase64String(Convert.ToBase64String(bResult)); var svgFragment = Encoding.ASCII.GetString(svgData); doc.LoadXml(svgFragment); } svgWindow.Document = doc; SvgSvgElement elm = (SvgSvgElement)doc.RootElement; int winWidth = (int)elm.Width.BaseVal.Value; int winHeight = (int)elm.Height.BaseVal.Value; if (winWidth == 0 || winHeight == 0) { var size = elm.GetSize(); winWidth = (int)size.Width; winHeight = (int)size.Height; } svgWindow.Resize(winWidth, winHeight); renderer.Render(elm as SvgElement); Image img = renderer.RasterImage; return(img); } MemoryStream ms = new MemoryStream(bResult); return(Image.FromStream(ms, element.ColorProfile != null)); } return(null); }