1

テキストはレンダリングできますが、svg 要素をレンダリングできません。レンダリングしようとしている html を svg ファイルとして保存すると、Internet Explorer は完全なイメージを本来の方法でレンダリングするので、入力データに問題はないと確信しています。

ここで、ウェブブラウザを起動するスレッドを起動します

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 を使用して動作しましたが、Web サーバーに Java がインストールされておらず、上司がインストールを拒否しました。ふりだしに戻る!

svg.dll をダウンロードし、部分的に動作するようにしました。svg 要素の一部をレンダリングしますが、テキストはレンダリングしません。

インターフェイスがないか、com オブジェクトを呼び出す必要があると思いますが、どのように、または何をすべきかわかりません。

4

1 に答える 1

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 コードを抽出すると、次のようになります。

<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);
于 2012-10-02T14:23:53.160 に答える