簡単な答えは、そのようにすることはできません。ただし、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 コードを抽出すると、次のようになります。
<svg xmlns="http://www.w3.org/2000/svg" width="945" height="325"....</svg>
つまり、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 はまだ機能しません。ただし、png にレンダリングされます。
最後に、必要な宣言をいくつか示します。
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);