/// <summary> /// Renders the specified HTML on top of the given image.<br/> /// <paramref name="image"/> will contain the rendered html in it on top of original content.<br/> /// <paramref name="image"/> must not contain transparent pixels as it will corrupt the rendered html text.<br/> /// See "Rendering to image" remarks section on <see cref="HtmlRender"/>.<br/> /// </summary> /// <param name="image">the image to render the html on</param> /// <param name="html">HTML source to render</param> /// <param name="location">the top-left most location to start render the html at</param> /// <param name="maxSize">the max size of the rendered html (if height above zero it will be clipped)</param> /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param> /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param> /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param> public static void RenderToImage(Image image, string html, PointF location, SizeF maxSize, CssData cssData = null, EventHandler <HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler <HtmlImageLoadEventArgs> imageLoad = null) { ArgChecker.AssertArgNotNull(image, "image"); if (!string.IsNullOrEmpty(html)) { // create memory buffer from desktop handle that supports alpha channel IntPtr dib; var memoryHdc = Win32Utils.CreateMemoryHdc(IntPtr.Zero, image.Width, image.Height, out dib); try { // create memory buffer graphics to use for HTML rendering using (var memoryGraphics = Graphics.FromHdc(memoryHdc)) { // draw the image to the memory buffer to be the background of the rendered html memoryGraphics.DrawImageUnscaled(image, 0, 0); // render HTML into the memory buffer RenderHtml(memoryGraphics, html, location, maxSize, cssData, false, stylesheetLoad, imageLoad); } // copy from memory buffer to image CopyBufferToImage(memoryHdc, image); } finally { Win32Utils.ReleaseMemoryHdc(memoryHdc, dib); } } }
/// <summary> /// Special draw logic to draw transparent text using GDI.<br/> /// 1. Create in-memory DC<br/> /// 2. Copy background to in-memory DC<br/> /// 3. Draw the text to in-memory DC<br/> /// 4. Copy the in-memory DC to the proper location with alpha blend<br/> /// </summary> private static void DrawTransparentText(IntPtr hdc, string str, RFont font, Point point, Size size, Color color) { IntPtr dib; var memoryHdc = Win32Utils.CreateMemoryHdc(hdc, size.Width, size.Height, out dib); try { // copy target background to memory HDC so when copied back it will have the proper background Win32Utils.BitBlt(memoryHdc, 0, 0, size.Width, size.Height, hdc, point.X, point.Y, Win32Utils.BitBltCopy); // Create and select font Win32Utils.SelectObject(memoryHdc, ((FontAdapter)font).HFont); Win32Utils.SetTextColor(memoryHdc, (color.B & 0xFF) << 16 | (color.G & 0xFF) << 8 | color.R); // Draw text to memory HDC Win32Utils.TextOut(memoryHdc, 0, 0, str, str.Length); // copy from memory HDC to normal HDC with alpha blend so achieve the transparent text Win32Utils.AlphaBlend(hdc, point.X, point.Y, size.Width, size.Height, memoryHdc, 0, 0, size.Width, size.Height, new BlendFunction(color.A)); } finally { Win32Utils.ReleaseMemoryHdc(memoryHdc, dib); } }
/// <summary> /// Renders the specified HTML into a new image of the requested size.<br/> /// The HTML will be layout by the given size but will be clipped if cannot fit.<br/> /// <p> /// Limitation: The image cannot have transparent background, by default it will be white.<br/> /// See "Rendering to image" remarks section on <see cref="HtmlRender"/>.<br/> /// </p> /// </summary> /// <param name="html">HTML source to render</param> /// <param name="size">The size of the image to render into, layout html by width and clipped by height</param> /// <param name="backgroundColor">optional: the color to fill the image with (default - white)</param> /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param> /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param> /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param> /// <returns>the generated image of the html</returns> /// <exception cref="ArgumentOutOfRangeException">if <paramref name="backgroundColor"/> is <see cref="Color.Transparent"/></exception>. public static Image RenderToImage(string html, Size size, Color backgroundColor = new Color(), CssData cssData = null, EventHandler <HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler <HtmlImageLoadEventArgs> imageLoad = null) { if (backgroundColor == Color.Transparent) { throw new ArgumentOutOfRangeException("backgroundColor", "Transparent background in not supported"); } // create the final image to render into var image = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppArgb); if (!string.IsNullOrEmpty(html)) { // create memory buffer from desktop handle that supports alpha channel IntPtr dib; var memoryHdc = Win32Utils.CreateMemoryHdc(IntPtr.Zero, image.Width, image.Height, out dib); try { // create memory buffer graphics to use for HTML rendering using (var memoryGraphics = Graphics.FromHdc(memoryHdc)) { memoryGraphics.Clear(backgroundColor != Color.Empty ? backgroundColor : Color.White); // render HTML into the memory buffer RenderHtml(memoryGraphics, html, Point.Empty, size, cssData, true, stylesheetLoad, imageLoad); } // copy from memory buffer to image CopyBufferToImage(memoryHdc, image); } finally { Win32Utils.ReleaseMemoryHdc(memoryHdc, dib); } } return(image); }
/// <summary> /// Renders the specified HTML on top of the given image.<br/> /// <paramref name="image"/> will contain the rendered html in it on top of original content.<br/> /// <paramref name="image"/> must not contain transparent pixels as it will corrupt the rendered html text.<br/> /// See "Rendering to image" remarks section on <see cref="HtmlRender"/>.<br/> /// </summary> /// <param name="image">the image to render the html on</param> /// <param name="html">HTML source to render</param> /// <param name="location">the top-left most location to start render the html at</param> /// <param name="maxSize">the max size of the rendered html (if height above zero it will be clipped)</param> /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param> /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param> /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param> public static void RenderToImage(Image image, IResourceServer resourceServer, PointF location, SizeF maxSize ) { ArgChecker.AssertArgNotNull(image, "image"); if (!string.IsNullOrEmpty(resourceServer.Html)) { // create memory buffer from desktop handle that supports alpha channel IntPtr dib; var memoryHdc = Win32Utils.CreateMemoryHdc(IntPtr.Zero, image.Width, image.Height, out dib); try { // create memory buffer graphics to use for HTML rendering using (var memoryGraphics = Graphics.FromHdc(memoryHdc)) { // draw the image to the memory buffer to be the background of the rendered html memoryGraphics.DrawImageUnscaled(image, 0, 0); // render HTML into the memory buffer RenderHtml(memoryGraphics, resourceServer, location, maxSize, false); } // copy from memory buffer to image CopyBufferToImage(memoryHdc, image); } finally { Win32Utils.ReleaseMemoryHdc(memoryHdc, dib); } } }
/// <summary> /// Renders the specified HTML into a new image of unknown size that will be determined by min/max width/height and HTML layout.<br/> /// If <paramref name="maxSize.Width"/> is zero the html will use all the required width, otherwise it will perform line /// wrap as specified in the html<br/> /// If <paramref name="maxSize.Height"/> is zero the html will use all the required height, otherwise it will clip at the /// given max height not rendering the html below it.<br/> /// If <paramref name="minSize"/> (Width/Height) is above zero the rendered image will not be smaller than the given min size.<br/> /// <p> /// Limitation: The image cannot have transparent background, by default it will be white.<br/> /// See "Rendering to image" remarks section on <see cref="HtmlRender"/>.<br/> /// </p> /// </summary> /// <param name="html">HTML source to render</param> /// <param name="minSize">optional: the min size of the rendered html (zero - not limit the width/height)</param> /// <param name="maxSize">optional: the max size of the rendered html, if not zero and html cannot be layout within the limit it will be clipped (zero - not limit the width/height)</param> /// <param name="backgroundColor">optional: the color to fill the image with (default - white)</param> /// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param> /// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param> /// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param> /// <returns>the generated image of the html</returns> /// <exception cref="ArgumentOutOfRangeException">if <paramref name="backgroundColor"/> is <see cref="Color.Transparent"/></exception>. public static Image RenderToImage(string html, Size minSize, Size maxSize, Color backgroundColor = new Color(), CssData cssData = null, EventHandler <HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler <HtmlImageLoadEventArgs> imageLoad = null) { if (backgroundColor == Color.Transparent) { throw new ArgumentOutOfRangeException("backgroundColor", "Transparent background in not supported"); } if (string.IsNullOrEmpty(html)) { return(new Bitmap(0, 0, PixelFormat.Format32bppArgb)); } using (var container = new HtmlContainer()) { container.AvoidAsyncImagesLoading = true; container.AvoidImagesLateLoading = true; if (stylesheetLoad != null) { container.StylesheetLoad += stylesheetLoad; } if (imageLoad != null) { container.ImageLoad += imageLoad; } container.SetHtml(html, cssData); var finalSize = MeasureHtmlByRestrictions(container, minSize, maxSize); container.MaxSize = finalSize; // create the final image to render into by measured size var image = new Bitmap(finalSize.Width, finalSize.Height, PixelFormat.Format32bppArgb); // create memory buffer from desktop handle that supports alpha channel IntPtr dib; var memoryHdc = Win32Utils.CreateMemoryHdc(IntPtr.Zero, image.Width, image.Height, out dib); try { // render HTML into the memory buffer using (var memoryGraphics = Graphics.FromHdc(memoryHdc)) { memoryGraphics.Clear(backgroundColor != Color.Empty ? backgroundColor : Color.White); container.PerformPaint(memoryGraphics); } // copy from memory buffer to image CopyBufferToImage(memoryHdc, image); } finally { Win32Utils.ReleaseMemoryHdc(memoryHdc, dib); } return(image); } }
public static Metafile RenderToMetafile(string html, float left = 0, float top = 0, float maxWidth = 0, CssData cssData = null, EventHandler <HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler <HtmlImageLoadEventArgs> imageLoad = null) { Metafile image; IntPtr dib; var memoryHdc = Win32Utils.CreateMemoryHdc(IntPtr.Zero, 1, 1, out dib); try { image = new Metafile(memoryHdc, EmfType.EmfPlusDual, ".."); using (var g = Graphics.FromImage(image)) { Render(g, html, left, top, maxWidth, cssData, stylesheetLoad, imageLoad); } } finally { Win32Utils.ReleaseMemoryHdc(memoryHdc, dib); } return(image); }
public static async Task <Metafile> RenderToMetafile(IResourceServer resourceServer, float left = 0, float top = 0, float maxWidth = 0 ) { Metafile image; IntPtr dib; var memoryHdc = Win32Utils.CreateMemoryHdc(IntPtr.Zero, 1, 1, out dib); try { image = new Metafile(memoryHdc, EmfType.EmfPlusDual, ".."); using (var g = Graphics.FromImage(image)) { Render(g, resourceServer, left, top, maxWidth); } } finally { Win32Utils.ReleaseMemoryHdc(memoryHdc, dib); } return(image); }