1

見つけたコードを使用して、SVGファイルを画像ファイルにラスタライズしています。リンクはhttp://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_24547525.htmlです。私のコードは同じように見えますが、次のアクセス違反が発生しています。

「保護されたメモリの読み取りまたは書き込みを試みました。これは、他のメモリが破損していることを示していることがよくあります。」`

明らかなことを排除するために:私はGimpディレクトリからsvgファイルを使用しているので、既知の良好なファイルがあります。私はe:をファイルの保存場所として使用して、ライブラリがセキュリティや許可に影響を与えないようにします。問題が発生した場合に備えて、管理者権限でVisualStudioを実行しています。私のボックスは64ビットで、Local.testsettingsを「64ビットマシンの64ピットプロセスでテストを実行する」に設定しています。

何か案は?

私のコードは次のとおりです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace TA.Rasterizer
{
    /// <summary>
    /// Takes SVG image file type and converts to PNG image file type. 
    /// Gimp must be installed. Gimp dll location must be in the web.config
    /// file key "ThreatAnalyzer-DllDirectoryForGimp".
    /// <summary>
    /// http://msdn.microsoft.com/en-us/magazine/cc164123.aspx
    /// http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_24547525.html
    /// </summary>    /// </summary>
    public static class Rasterizer
    {
        // C:\Windows\System32
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool SetDllDirectory(string pathname);

        [DllImport("libgobject-2.0-0.dll", SetLastError = true)]
        static extern void g_type_init();

        [DllImport("librsvg-2-2.dll", SetLastError = true)]
        static extern IntPtr rsvg_pixbuf_from_file_at_size(string file_name, int width, int height, out IntPtr error);

        [DllImport("libgdk_pixbuf-2.0-0.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
        static extern bool gdk_pixbuf_save(IntPtr pixbuf, string filename, string type, out IntPtr error, __arglist);
        //static extern bool gdk_pixbuf_save_to_buffer(

        /// <summary>
        /// Get location of Gimp installed Dlls from web.config appsettings key/value.
        /// Key name is found in this.webConfigFileAppSettingsGimp
        /// </summary>
        /// <returns></returns>
        private static string GetGimpDllLocationFromConfigurationFile(bool webapp, string nonDefaultConfigFileName)
        {
            // connect to config file
            Configuration rasterizerConfiguration = new TA.Rasterizer.Configuration(webapp, nonDefaultConfigFileName);

            // grab config setting
            return rasterizerConfiguration.Get("ThreatAnalyzer-DllDirectoryForGimp");
        }

        /// <summary>
        /// http://msdn.microsoft.com/en-us/magazine/cc164123.aspx
        /// You must check that file exists after call in order to check success. 
        /// </summary>
        /// <param name="inputFileName">SVG file to be converted</param>
        /// <param name="outputFileName">PNG file as final product</param>
        /// <returns></returns>
        public static void SvgToPng(string inputFileName, string outputFileName, bool webapp, string nonDefaultConfigFileName)
        {
            string gimpDllLocation = GetGimpDllLocationFromConfigurationFile(webapp, nonDefaultConfigFileName);

            bool rasterizeSuccess = ExternRaster.RasterizeSvg(inputFileName, outputFileName, gimpDllLocation);

            if (!rasterizeSuccess)
            {
                Int32 err = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                throw new Win32Exception(err);
            }
        }

    /// <summary>
    /// http://msdn.microsoft.com/en-us/magazine/cc164123.aspx
    /// http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_24547525.html
    /// </summary>
    internal sealed class ExternRaster
    {

        public static bool RasterizeSvg(string inputFileName, string outputFileName, string gimpDllLocation)
        {
            bool callSuccessful = SetDllDirectory(gimpDllLocation);
            if (!callSuccessful)
            {
                throw new Exception("Could not set DLL directory");
            }
            g_type_init();
            IntPtr error1;
            IntPtr result = rsvg_pixbuf_from_file_at_size(@"E:\green.svg", -1, -1, out error1);
            if (error1 != IntPtr.Zero)
            {
                throw new Exception(Marshal.ReadInt32(error1).ToString());
            }

            IntPtr error2;
            callSuccessful = gdk_pixbuf_save(result, @"E:\green.jpg", "jpg", out error2, __arglist(null));
            if (!callSuccessful)
            {
                throw new Exception(error2.ToInt32().ToString());
            }

            return true;
        }

    }



    }
}

MSTestユニットテストからコードにアクセスします。

    /// <summary>
    ///A test for RasterizeSvg
    ///</summary>
    [TestMethod()]
    public void RasterizeSvgTest()
    {
        // arrange
        string svgFileNameInAppDirectory = "1kijvsrewxxr3mdvlwitjvyu-pie.svg";

        string currentClassLibDirectory = Environment.CurrentDirectory.Replace(@"\bin\debug\","");
        string pathToAppData = Setup.GetDataPath(); 
        string inputFileName = Path.Combine(pathToAppData, svgFileNameInAppDirectory);
        string outputFileName = Path.Combine(pathToAppData, svgFileNameInAppDirectory.Replace("svg","png"));
        bool webapp = false; 
        string nonDefaultConfigFileName = string.Empty; 

        // act
        Rasterizer.SvgToPng(inputFileName, outputFileName, webapp, nonDefaultConfigFileName);

        // assert
        bool fileExists = File.Exists(outputFileName);
        Assert.IsTrue(fileExists);

        // cleanup
        if (fileExists)
        {
            File.Delete(outputFileName);
        }
    }
4

1 に答える 1

1

ドキュメントにrsvg_pixbuf_from_file_at_sizeは、

エラーが発生した場合、エラーが設定され、NULL が返されます。

私にとって、これは、成功した場合、error1変数が有効なポインターに設定されないことを意味します。代わりに戻り値をテストする必要がありますresult

「jpg」と「jpeg」について@GojiraDemonstahが言ったことも重要だと思います。

さらに、rsvg_pixbuf_from_file_at_size新しいものを割り当てGdkPixbufますが、それを解放するコードはありません。これを行うには、あなたも持っている必要があります

[DllImport("libgobject-2.0-0.dll", SetLastError = true)]
static extern void g_object_unref(IntPtr obj);

あなたのインポートで

g_object_unref(result);

gdk_pixbuf_saveメモリリークを避けるために呼び出した後。

于 2013-06-17T13:24:35.933 に答える