我可以渲染文本,但无法渲染svg元素。当我保存html我试图渲染为svg文件时,Internet Explorer将以它应该的方式呈现完整的图像,所以我相当自信我的输入数据是正常的。
这里是我启动启动webbrowser
的线程的地方Browserinfo bi = new Browserinfo(height, width, rsltPath, stype);
bi.Temphtml = temphtml.Replace("\\", "/");
Thread webBrowseThread = new Thread(new ParameterizedThreadStart(PerformWebBrowseOp));
webBrowseThread.SetApartmentState(ApartmentState.STA);
webBrowseThread.Start(bi);
bi.Temphtml是我保存输入数据的文件。这是文件的外观(删除了内容)
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><svg xmlns="http://www.w3.org/2000/svg"
..svg data...
</svg></body></html>
这是实际代码:
private void PerformWebBrowseOp(object obj)
{
Browserinfo bi = (Browserinfo)obj;
using (Bitmap bitmap = new Bitmap(bi.Width, bi.Height))
{
using (WebBrowser webBrowser = new WebBrowser())
{
webBrowser.Navigate("file:///"+bi.Temphtml);
while (webBrowser.Document.Body == null)
{
Application.DoEvents();
}
IHTMLDocument2 rawDoc = (IHTMLDocument2)webBrowser.Document.DomDocument;
//rawDoc.write(sbody);
IHTMLElement rawBody = rawDoc.body;
IHTMLElementRender2 render = (IHTMLElementRender2)rawBody;
Rectangle bitmapRect = new Rectangle(0, 0, bi.Width, bi.Height);
webBrowser.DrawToBitmap(bitmap, bitmapRect);
System.Drawing.Imaging.Encoder qualityEncoder = System.Drawing.Imaging.Encoder.Quality;
var quality = (long)100;
using (EncoderParameter ratio = new EncoderParameter(qualityEncoder, quality))
{
using (EncoderParameters codecParams = new EncoderParameters(1))
{
codecParams.Param[0] = ratio;
ImageCodecInfo ici = null;
if (bi.ImgType == "jpg")
{
ici = GetImageEncoder(ImageFormat.Jpeg);
}
else
{
ici = GetImageEncoder(ImageFormat.Png);
}
bitmap.Save(bi.SavePath, ici, codecParams);
}
}
}
}
((AutoResetEvent)waithandle[0]).Set();
}
为了保持讨论重点,以下注释可能会有所帮助: 我最初使用Batik并让它工作,但我的网络服务器上没有安装Java,老板拒绝安装它。回到绘图板!
我下载了svg.dll,并让它部分正常工作。它将呈现svg元素的一部分,但不呈现文本。
我认为我缺少一个界面或者应该调用一个com对象,但不知道如何操作或做什么。
答案 0 :(得分:1)
简单的回答,你不能那样做。但是你可以用librsvg来做。我复制了下面的代码,该代码适用于png,但不适用于jpeg。如果有人能看到jpeg部分的错误,请告诉我。
您需要的文件是:
freetype6.dll
intl.dll
libcairo-2.dll
libcroco-0.6-3.dll
libexpat-1.dll
libfontconfig-1.dll
libgdk-win32-2.0-0.dll
libgdk_pixbuf-2.0-0.dll
libgio-2.0-0.dll
libglib-2.0-0.dll
libgmodule-2.0-0.dll
libgobject-2.0-0.dll
libgthread-2.0-0.dll
libgtk-win32-2.0-0.dll
libpango-1.0-0.dll
libpangocairo-1.0-0.dll
libpangoft2-1.0-0.dll
libpangowin32-1.0-0.dll
libpixbufloader-svg.dll
libpng14-14.dll
librsvg-2-2.dll
libxml2-2.dll
zlib1.dll
来自html页面的svg代码的摘录应该如下所示。
&lt; svg xmlns =“http://www.w3.org/2000/svg”width =“945”height =“325”....&lt; / svg&gt;
换句话说,除了svg标签中的内容之外,除掉所有的html
这是C#例程
private void RasterizeSvg(string tempsvg, string rsltPath, int _width, int _height, string formattype)
{
string slib = ConfigurationManager.AppSettings["LibrSvgPath"];
if (slib == null)
{
slib = @"C:\Librsvg";
}
bool callSuccessful = SetDllDirectory(slib);
if (!callSuccessful)
{
throw new Exception("Could not set DLL directory");
}
// g_type_init is critical for the png to save correctly
g_type_init();
rsvg_init();
IntPtr error = IntPtr.Zero;
IntPtr rsvghandle = rsvg_handle_new_from_file(tempsvg, out error);
if (error != IntPtr.Zero)
{
throw new Exception(Marshal.ReadInt32(error).ToString());
}
rsvg_handle_close(rsvghandle, out error);
if (error != IntPtr.Zero)
{
throw new Exception(Marshal.ReadInt32(error).ToString());
}
IntPtr cairosurface = cairo_image_surface_create(cairo_format_t.CAIRO_FORMAT_RGB24, _width, _height);
IntPtr cairocontext = cairo_create(cairosurface);
bool brslt = rsvg_handle_render_cairo(rsvghandle, cairocontext);
cairo_destroy(cairocontext);
if (formattype == "png")
{
cairo_surface_write_to_png(cairosurface, rsltPath);
cairo_surface_destroy(cairosurface);
}
else
{
//jpeg not working. the problem is how to convert from a cairo surface to a pixbuf
// once we figure that out, we can implement the jpeg conversion
/*option 1*/
//IntPtr pixbuf = cairo_create(cairosurface);
//cairo_set_source_surface(pixbuf, cairosurface, 0, 0);
//cairo_rectangle(pixbuf, 0, 0, _width, _height);
//cairo_fill(pixbuf);
//error = IntPtr.Zero;
/*option 2*/
IntPtr pixbuf = rsvg_handle_get_pixbuf(rsvghandle);
rsvg_handle_close(rsvghandle, out error);
cairo_surface_destroy(cairosurface);
gdk_init(0, "");
callSuccessful = gdk_pixbuf_save(pixbuf, rsltPath, formattype, out error);
gdk_exit(out error);
if (!callSuccessful)
{
throw new Exception(error.ToInt32().ToString());
}
/* need to release pixbuf memory*/
}
g_object_unref(rsvghandle);
}
正如我在顶部所说,jpeg还没有奏效。但它会呈现出来。
最后,这里有一些你需要的声明
enum cairo_format_t
{
CAIRO_FORMAT_INVALID = -1,
CAIRO_FORMAT_ARGB32 = 0,
CAIRO_FORMAT_RGB24 = 1,
CAIRO_FORMAT_A8 = 2,
CAIRO_FORMAT_A1 = 3,
CAIRO_FORMAT_RGB16_565 = 4,
CAIRO_FORMAT_RGB30 = 5
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
static extern bool SetDllDirectory(string pathname);
[DllImport("libgobject-2.0-0.dll", SetLastError = true)]
static extern void g_type_init();
[DllImport("libgobject-2.0-0.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern void g_object_unref(IntPtr obj);
[DllImport("librsvg-2-2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern bool rsvg_handle_render_cairo(IntPtr handle, IntPtr cairorenderer);
[DllImport("librsvg-2-2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern IntPtr rsvg_handle_get_pixbuf(IntPtr _rsvghandle);
[DllImport("librsvg-2-2.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern IntPtr rsvg_handle_new_from_file(string file_name, out IntPtr error);
[DllImport("librsvg-2-2.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern bool rsvg_handle_close(IntPtr _rsvghandle, out IntPtr error);
[DllImport("librsvg-2-2.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern void rsvg_init();
[DllImport("libcairo-2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern IntPtr cairo_create(IntPtr cairo_surface_t);
[DllImport("libcairo-2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern IntPtr cairo_image_surface_create(cairo_format_t _pixformat, int width, int height);
[DllImport("libcairo-2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern void cairo_surface_write_to_png(IntPtr cairo_surface_t, string filename);
[DllImport("libcairo-2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern void cairo_set_source_surface(IntPtr destbuf, IntPtr srcsuface, double x, double y);
[DllImport("libcairo-2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern void cairo_rectangle(IntPtr buf, double x, double y, double width, double height);
[DllImport("libcairo-2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern void cairo_fill(IntPtr destbuf);
[DllImport("libcairo-2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern void cairo_destroy(IntPtr buf);
[DllImport("libcairo-2.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern void cairo_surface_destroy(IntPtr buf);
[DllImport("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern bool gdk_pixbuf_save(IntPtr pixbuf, string filename, string type, out IntPtr error);
[DllImport("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern IntPtr gdk_pixbuf_get_from_drawable(IntPtr dest, IntPtr src, IntPtr cmap, int srcx, int srcy, int destx, int desty, int width, int height);
[DllImport("libgdk-win32-2.0-0.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern void gdk_init(int argcnt, string args);
[DllImport("libgdk-win32-2.0-0.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
static extern void gdk_exit(out IntPtr error);