Render HTML and CSS to a PNG in C# with OneRender: a 1200 by 630 social card with a gradient and a logo, and a badge on a transparent background at three times the pixel density.
using OneRender.Image; using OneRender.Painting; string title = "Shipping weekly: 444 orders"; string html = $$""" <!DOCTYPE html> <html lang="en"> <style> body { margin: 0; width: 1200px; height: 630px; display: flex; flex-direction: column; justify-content: space-between; box-sizing: border-box; padding: 72px; font-family: sans-serif; color: #fff; background: linear-gradient(135deg, #16202c, #1d4ed8) } h1 { font-size: 64px; line-height: 1.1; margin: 0; max-width: 900px } footer { display: flex; align-items: center; gap: 20px; font-size: 28px; opacity: .85 } </style> <body> <h1>{{System.Net.WebUtility.HtmlEncode(title)}}</h1> <footer><img src="logo.png" width="64" height="64" alt=""> example.com/blog</footer> </body> </html> """; RgbaImage card = HtmlRender.ToImage(html, new HtmlRenderOptions { Width = 1200, Height = 630, BaseUrl = "file:///cards/", Resources = url => url == "file:///cards/logo.png" ? File.ReadAllBytes("logo.png") : null, }); File.WriteAllBytes("card.png", card.ToPng()); Console.WriteLine($"card.png: {card.Width}x{card.Height}"); // A badge on a transparent background, at 3x for high-density screens. RgbaImage badge = HtmlRender.ToImage( "<body style='margin:0'><span style='display:inline-block;padding:4px 10px;border-radius:999px;background:#16a34a;color:#fff;font:600 14px sans-serif'>Passing</span>", new HtmlRenderOptions { Width = 80, Height = 27, DevicePixelRatio = 3, PageColor = PaintColor.Transparent }); File.WriteAllBytes("badge.png", badge.ToPng()); Console.WriteLine($"badge.png: {badge.Width}x{badge.Height}, corner alpha {badge.Pixels[3]}");
card.png: 1200x630 badge.png: 240x81, corner alpha 0
The options
WidthandHeightare the viewport in CSS pixels, from 1 to 16,384. The image shows exactly the viewport; content below it is cut off. To capture a whole page, measure it first: see Replace a headless browser.DevicePixelRatioscales the pixels, not the layout: the badge is laid out at 80 by 27 and drawn at 240 by 81.PageColoris painted where the document paints no background. The default is opaque white;PaintColor.Transparentleaves those pixels clear.Resourcessupplies images, style sheets and fonts by absolute address, andBaseUrlis what relative references resolve against. The engine fetches nothing itself.AnimationTimeshows CSS animations and transitions as they look that many milliseconds in. Without it, the page is drawn with no animation applied.
The image
RgbaImage holds Width * Height * 4 bytes of 8-bit RGBA in Pixels, row by row from the top left, ready to hand to another library or a texture upload. ToPng() encodes it.
Good to know
- Images in the page are decoded by OneImage (PNG, JPEG, WebP, GIF, TIFF, BMP and ICO), and inline
<svg>is drawn. An<img>pointing to an SVG file isn’t drawn in 1.0.0; inline the SVG instead. - Rendering is deterministic: the same HTML, resources and fonts give the same pixels on every machine, so snapshot tests can compare bytes.
- Text uses the bundled fonts unless you add more: see Fonts.
The rasterizer and everything it draws are described in the overview and the display list.