2

ウィンドウにドロップされたファイルをGdk.Pixbufとしてロードして表示するC#/ Mono / Gtk#プログラムがあります。

Ubuntuでうまく機能します。しかし、Windowsでは、C:\áéíóú.jpgなどの非ASCIIファイル名のファイルをドロップしようとすると、プログラムがクラッシュします。最初は自分のコードに問題があると思いました。そこで、簡単なテストケースを作成しました。

Console.WriteLine("{0} exists? {1}", Filename, File.Exists(Filename));
Pixbuf pixels = new Pixbuf (Filename)

出力

C:\áéíóú.jpgは存在しますか?True
GLib.GException:ファイル'C:\áéíóú.jpg'を開けませんでした:そのようなファイルまたはディレクトリはありません

結局のところ、Glibは存在するファイルを把握できません。また、Unicodeファイル名からWindowsのPixbufに画像ファイルをロードできるように修正する方法がわかりません。

4

1 に答える 1

2

これは、gtk-sharp<->gdk-pixbufの相互運用に問題があるようです。

どうやらWindowsを除くすべてのOSgdk_pixbuf_new_from_fileで、utf8でエンコードされたファイル名を取ります。ただし、Windowsでは、この関数の名前が変更さgdk_pixbuf_new_from_file_utf8れ、ロケール変換を実行してutf8バージョンの呼び出しに進むラッパーに置き換えられます。gtk-sharpはこれを認識せずgdk_pixbuf_new_from_file、utf8引数の受け渡しを使用するため、Windowsでの予期しない余分なロケール変換によりファイル名が破損します。

Pixbuf回避策として、ファイル名の代わりにコンストラクターを使用することを提案しましStreamたが、投稿者は画像を正しくロードしないと報告しています。

更新: 幸い、Pixbufラッパークラスには、既存のpixbufオブジェクトの生のIntPtrを受け入れるコンストラクターがあります。そのため、バグのあるコンストラクターのコードは、次のようないくつかのヘルパーメソッドで複製、修正、および非表示にすることができます。

[DllImport("libgdk_pixbuf-2.0-0.dll")]
static extern IntPtr gdk_pixbuf_new_from_file_utf8(IntPtr filename, out IntPtr error);

static Pixbuf CreatePixbufWin32(string filename)
{
    IntPtr native_filename = GLib.Marshaller.StringToPtrGStrdup(filename);
    IntPtr error = IntPtr.Zero;
    IntPtr raw = gdk_pixbuf_new_from_file_utf8(native_filename, out error);
    GLib.Marshaller.Free(native_filename);
    if (error != IntPtr.Zero) throw new GLib.GException(error);
    return new Pixbuf(raw);
}

static Pixbuf CreatePixbuf(string filename)
{
    if (Environment.OSVersion.Platform == PlatformID.Win32NT)
    {
        return CreatePixbufWin32(filename);
    }
    return new Pixbuf(filename);
}

私はこれを成功裏にテストしました。お役に立てれば。

于 2012-10-18T18:38:50.913 に答える