Skip to content

Commit a68a5bc

Browse files
author
ArthurHub
committed
* improve RenderToImage
1 parent f953b53 commit a68a5bc

File tree

1 file changed

+46
-9
lines changed

1 file changed

+46
-9
lines changed

Source/HtmlRenderer/HtmlRender.cs

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ public static SizeF Render(Graphics g, string html, PointF location, SizeF maxSi
196196
container.MaxSize = maxSize;
197197
container.PerformLayout(g);
198198
container.PerformPaint(g);
199-
199+
200200
if (prevClip != null)
201201
{
202202
g.SetClip(prevClip, CombineMode.Replace);
@@ -223,8 +223,12 @@ public static SizeF Render(Graphics g, string html, PointF location, SizeF maxSi
223223
/// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
224224
/// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
225225
/// <returns>the generated image of the html</returns>
226+
/// <exception cref="ArgumentOutOfRangeException">if <paramref name="backgroundColor"/> is <see cref="Color.Transparent"/></exception>.
226227
public static Image RenderToImage(string html, Size size, Color backgroundColor = new Color(), CssData cssData = null, EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
227228
{
229+
if (backgroundColor == Color.Transparent)
230+
throw new ArgumentOutOfRangeException("backgroundColor", "Transparent background in not supported");
231+
228232
// create the final image to render into
229233
var image = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppArgb);
230234

@@ -285,12 +289,43 @@ public static SizeF Render(Graphics g, string html, PointF location, SizeF maxSi
285289
/// <param name="maxWidth">the max width of the rendered html</param>
286290
/// <param name="maxHeight">optional: the max height of the rendered html, if above zero it will be clipped</param>
287291
/// <param name="backgroundColor">optional: the color to fill the image with (default - white)</param>
288-
/// <param name="cssData">optiona: the style to use for html rendering (default - use W3 default style)</param>
292+
/// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
289293
/// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
290294
/// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
291295
/// <returns>the generated image of the html</returns>
292-
public static Image RenderToImage(string html, int maxWidth, int maxHeight = 0, Color backgroundColor = new Color(), CssData cssData = null, EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
296+
/// <exception cref="ArgumentOutOfRangeException">if <paramref name="backgroundColor"/> is <see cref="Color.Transparent"/></exception>.
297+
public static Image RenderToImage(string html, int maxWidth, int maxHeight = 0, Color backgroundColor = new Color(), CssData cssData = null,
298+
EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
293299
{
300+
return RenderToImage(html, Size.Empty, new Size(maxWidth, maxHeight), backgroundColor, cssData, stylesheetLoad, imageLoad);
301+
}
302+
303+
/// <summary>
304+
/// Renders the specified HTML into image of unknown size that will be determined by max width/height and HTML layout.<br/>
305+
/// If <paramref name="maxSize.Width"/> is zero the html will use all the required width, otherwise it will perform line
306+
/// wrap as specified in the html<br/>
307+
/// If <paramref name="maxSize.Height"/> is zero the html will use all the required height, otherwise it will clip at the
308+
/// given max height not rendering the html below it.<br/>
309+
/// If <paramref name="minSize"/> (Width/Height) is above zero the rendered image will not be smaller than the given min size.<br/>
310+
/// <p>
311+
/// Limitation: The image cannot have transparent background, by default it will be white.
312+
/// </p>
313+
/// </summary>
314+
/// <param name="html">HTML source to render</param>
315+
/// <param name="minSize">the max width of the rendered html</param>
316+
/// <param name="maxSize">optional: the max height of the rendered html, if above zero it will be clipped</param>
317+
/// <param name="backgroundColor">optional: the color to fill the image with (default - white)</param>
318+
/// <param name="cssData">optional: the style to use for html rendering (default - use W3 default style)</param>
319+
/// <param name="stylesheetLoad">optional: can be used to overwrite stylesheet resolution logic</param>
320+
/// <param name="imageLoad">optional: can be used to overwrite image resolution logic</param>
321+
/// <returns>the generated image of the html</returns>
322+
/// <exception cref="ArgumentOutOfRangeException">if <paramref name="backgroundColor"/> is <see cref="Color.Transparent"/></exception>.
323+
public static Image RenderToImage(string html, Size minSize, Size maxSize, Color backgroundColor = new Color(), CssData cssData = null,
324+
EventHandler<HtmlStylesheetLoadEventArgs> stylesheetLoad = null, EventHandler<HtmlImageLoadEventArgs> imageLoad = null)
325+
{
326+
if (backgroundColor == Color.Transparent)
327+
throw new ArgumentOutOfRangeException("backgroundColor", "Transparent background in not supported");
328+
294329
if (string.IsNullOrEmpty(html))
295330
return new Bitmap(0, 0, PixelFormat.Format32bppArgb);
296331

@@ -305,23 +340,25 @@ public static SizeF Render(Graphics g, string html, PointF location, SizeF maxSi
305340
htmlContainer.ImageLoad += imageLoad;
306341
htmlContainer.SetHtml(html, cssData);
307342

343+
// first layout without size restriction to know html actual size
308344
htmlContainer.PerformLayout(measureGraphics);
309345

310-
if (maxWidth > 0 && maxWidth < htmlContainer.ActualSize.Width)
346+
if (maxSize.Width > 0 && maxSize.Width < htmlContainer.ActualSize.Width)
311347
{
312348
// to allow the actual size be smaller than max we need to set max size only if it is really larger
313-
htmlContainer.MaxSize = new SizeF(maxWidth, 0);
349+
htmlContainer.MaxSize = new SizeF(maxSize.Width, 0);
314350
htmlContainer.PerformLayout(measureGraphics);
315351
}
316352
}
317353

318-
var size = new Size(maxWidth > 0 ? Math.Min(maxWidth, (int) htmlContainer.ActualSize.Width) : (int) htmlContainer.ActualSize.Width,
319-
maxHeight > 0 ? Math.Min(maxHeight, (int) htmlContainer.ActualSize.Height) : (int) htmlContainer.ActualSize.Height);
354+
// restrict the final size by min/max
355+
var finalWidth = Math.Max(maxSize.Width > 0 ? Math.Min(maxSize.Width, (int)htmlContainer.ActualSize.Width) : (int)htmlContainer.ActualSize.Width, minSize.Width);
356+
var finalHeight = Math.Max(maxSize.Height > 0 ? Math.Min(maxSize.Height, (int)htmlContainer.ActualSize.Height) : (int)htmlContainer.ActualSize.Height, minSize.Height);
320357

321358
// create the final image to render into by measured size
322-
var image = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppArgb);
359+
var image = new Bitmap(finalWidth, finalHeight, PixelFormat.Format32bppArgb);
323360

324-
// create memory buffer from desktop handle that supports alpha chanel
361+
// create memory buffer from desktop handle that supports alpha channel
325362
IntPtr dib;
326363
var memoryHdc = Win32Utils.CreateMemoryHdc(IntPtr.Zero, image.Width, image.Height, out dib);
327364
try

0 commit comments

Comments
 (0)