score:11
you have possibly tried iecapt. i think it is the right way to go. i created a modified version of it and use a timer
instead of thread.sleep
it captures your site as expected.
------edit------
here is the ugly source. just add a reference to microsoft html object library
.
and this is the usage:
htmlcapture capture = new htmlcapture(@"c:\temp\myimg.png");
capture.htmlimagecapture += new htmlcapture.htmlcaptureevent(capture_htmlimagecapture);
capture.create("http://www.highcharts.com/demo/combo-dual-axes");
void capture_htmlimagecapture(object sender, uri url)
{
this.close();
}
file1
using system;
using system.collections.generic;
using system.componentmodel;
using system.data;
using system.drawing;
using system.linq;
using system.text;
using system.windows.forms;
using system.io;
namespace myiecapt
{
public class htmlcapture
{
private webbrowser web;
private timer tready;
private rectangle screen;
private size? imgsize = null;
//an event that triggers when the html document is captured
public delegate void htmlcaptureevent(object sender, uri url);
public event htmlcaptureevent htmlimagecapture;
string filename = "";
//class constructor
public htmlcapture(string filename)
{
this.filename = filename;
//initialise the webbrowser and the timer
web = new webbrowser();
tready = new timer();
tready.interval = 2000;
screen = screen.primaryscreen.bounds;
//set the webbrowser width and hight
web.width = 1024; //screen.width;
web.height = 768; // screen.height;
//suppress script errors and hide scroll bars
web.scripterrorssuppressed = true;
web.scrollbarsenabled = false;
//attached events
web.navigating +=
new webbrowsernavigatingeventhandler(web_navigating);
web.documentcompleted += new
webbrowserdocumentcompletedeventhandler(web_documentcompleted);
tready.tick += new eventhandler(tready_tick);
}
public void create(string url)
{
imgsize = null;
web.navigate(url);
}
public void create(string url, size imgsz)
{
this.imgsize = imgsz;
web.navigate(url);
}
void web_documentcompleted(object sender,
webbrowserdocumentcompletedeventargs e)
{
//start the timer
tready.start();
}
void web_navigating(object sender, webbrowsernavigatingeventargs e)
{
//stop the timer
tready.stop();
}
void tready_tick(object sender, eventargs e)
{
try
{
//stop the timer
tready.stop();
mshtml.ihtmldocument2 docs2 = (mshtml.ihtmldocument2)web.document.domdocument;
mshtml.ihtmldocument3 docs3 = (mshtml.ihtmldocument3)web.document.domdocument;
mshtml.ihtmlelement2 body2 = (mshtml.ihtmlelement2)docs2.body;
mshtml.ihtmlelement2 root2 = (mshtml.ihtmlelement2)docs3.documentelement;
// determine dimensions for the image; we could add minwidth here
// to ensure that we get closer to the minimal width (the width
// computed might be a few pixels less than what we want).
int width = math.max(body2.scrollwidth, root2.scrollwidth);
int height = math.max(root2.scrollheight, body2.scrollheight);
//get the size of the document's body
rectangle docrectangle = new rectangle(0, 0, width, height);
web.width = docrectangle.width;
web.height = docrectangle.height;
//if the imgsize is null, the size of the image will
//be the same as the size of webbrowser object
//otherwise set the image size to imgsize
rectangle imgrectangle;
if (imgsize == null) imgrectangle = docrectangle;
else imgrectangle = new rectangle() { location = new point(0, 0), size = imgsize.value };
//create a bitmap object
bitmap bitmap = new bitmap(imgrectangle.width, imgrectangle.height);
//get the viewobject of the webbrowser
iviewobject ivo = web.document.domdocument as iviewobject;
using (graphics g = graphics.fromimage(bitmap))
{
//get the handle to the device context and draw
intptr hdc = g.gethdc();
ivo.draw(1, -1, intptr.zero, intptr.zero,
intptr.zero, hdc, ref imgrectangle,
ref docrectangle, intptr.zero, 0);
g.releasehdc(hdc);
}
//invoke the htmlimagecapture event
bitmap.save(filename);
bitmap.dispose();
}
catch
{
//system.diagnostics.process.getcurrentprocess().kill();
}
if(htmlimagecapture!=null) htmlimagecapture(this, web.url);
}
}
}
and file2
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.drawing;
using system.runtime.interopservices;
namespace myiecapt
{
[comvisible(true), comimport()]
[guidattribute("0000010d-0000-0000-c000-000000000046")]
[interfacetypeattribute(cominterfacetype.interfaceisiunknown)]
public interface iviewobject
{
[return: marshalas(unmanagedtype.i4)]
[preservesig]
int draw(
[marshalas(unmanagedtype.u4)] uint32 dwdrawaspect,
int lindex,
intptr pvaspect,
[in] intptr ptd,
intptr hdctargetdev,
intptr hdcdraw,
[marshalas(unmanagedtype.struct)] ref rectangle lprcbounds,
[marshalas(unmanagedtype.struct)] ref rectangle lprcwbounds,
intptr pfncontinue,
[marshalas(unmanagedtype.u4)] uint32 dwcontinue);
[preservesig]
int getcolorset([in, marshalas(unmanagedtype.u4)] int dwdrawaspect,
int lindex, intptr pvaspect, [in] intptr ptd,
intptr hictargetdev, [out] intptr ppcolorset);
[preservesig]
int freeze([in, marshalas(unmanagedtype.u4)] int dwdrawaspect,
int lindex, intptr pvaspect, [out] intptr pdwfreeze);
[preservesig]
int unfreeze([in, marshalas(unmanagedtype.u4)] int dwfreeze);
}
}
score:0
thread.sleep
will simply suspend the thread your web browser is running on - how do you expect it to render anything when it is suspended? :)
instead, you need to allow the thread to process work. you can achieve this with a combination of thread.sleep(0)
and application.doevents()
, with something like the following:
datetime finish = datetime.now.addseconds(3);
while (datetime.now < finish) {
application.doevents();
thread.sleep(0);
}
score:0
@l.b , thank you for the help!
just an fyi for anyone wanting to run it in a class library, webbrowser needs to single threaded apartment, so do something like this:
var t = new thread(initanddo); //initanddo would have your code creating the webbrowser object etc...
t.setapartmentstate(apartmentstate.sta);
t.start();
then the gotcha, after the navigate call is done, add this line of code so that you get the completed navigation event:
web.navigate(url);
application.run();
score:0
i created a nuget package for this purpose https://github.com/dcumin39/renderhighcharts/wiki
Source: stackoverflow.com
Related Query
- Capturing webpage as image in c#, ensuring javascript rendered elements are visible
- highcharts change rendered image source on click
- Use django variable (array of elements from sqlite3 database) inside javascript embedded code
- JavaScript - Export Div with SVG chart + HTML as and Image
- Optimize JavaScript DrillDown code
- JavaScript code inside TypeScript file .ts not working
- c# WPF Webbrowser with Highchart, Javascript from external source not working "An error has occurred in the script on this page"
- Fonts are not showing up in the Export server rendered files
- passing formatting JavaScript code to HighCharts with JSON
- Embed javascript code in a django template
- Adding tool-tip to an image rendered using Highcharts Renderer.image() api
- Rotating a donut chart in javascript after it is rendered
- HTML Content to Javascript Code
- Strange character in the Highstock source code
- Angular HighCharts Show All Elements even there are big differance between amounts
- tool that shows javascript errors in code
- Plotting using highcharts.js labels are being rendered off-center in stead of being centered
- Javascript - convert HTML div with SVG to image
- Repeating Javascript Code
- Highcharts Pie chart export, labels are rendered twice
- Error: Data source must be a URL for refresh | console error | javascript | Highcharts
- Javascript Code not running in Wordpress Pages
- Decimals on yAxis are not being displayed, even if that same code works on highcharts jsfiddle
- highcharts: there are no data in exported image
- Tools for building charting server that creates / caches server-side rendered image charts?
- Highcharts nodes are not rendered wide enough
- Highcharts elements are not aligned
- Why are Bootstrap tabs displaying tab-pane divs with incorrect widths when using highcharts?
- Javascript relative time 24 hours ago etc as time
- Manage multiple highchart charts in a single webpage
More Query from same tag
- HighStock import issues with Angular 2
- Highcharts chart doesn't show all data points in X axis
- Highcharts zoom issue when panning reversed xAxis
- Multidimensional JSON to javascript array for highcharts
- Update two series on the same graph dynamically with HighCharts
- Highstock lineWidth
- Highcharts Scatter Plot - How to Fix Overlapping Data Labels?
- Highcharts - Can't change line colors
- Heroku and HighCharts Rails Gem -
- Highstock title setting via options
- Highchart is not defining angular 9
- Range Selector in Are Graph of High Chart
- How disable the 'k' dislay in Highcharts ordinate?
- Graph getting hidden while zooming in ( using the zoom scroll bar )
- Highcharts inactive state must be applied to all items except for hovered item
- Highcharts stock chart time selector
- Getting callback is not a function in JS with Highcharts
- asp net gridview to highcharts
- Highcharts xAxis values index
- Object [object Object] has no method 'highcharts'
- Highcharts not starting at give start time
- Vertical line on highchart, with position tied to animation frame from another div?
- How to translate the "Start" and "End" label in the tooltip of a Highcharts Gantt?
- Unable to customize the box to short single line in 'boxplot' type Highcharts
- HighStock y-axis labels changing by itself when horizontal scroll moves
- How can you change the "label" (valueSuffix) on a highcharts gauge after the gauge has been created?
- Why is one day's null data two days wide?
- Emulating multiple click functions or have separate clicked values based on specific areas below or above dataMin and dataMax - highcharts
- Highcharts: Get stack of series
- Dynamically add/remove xaxis categories in Highcharts