2012-10-18 13 views
2

我有一個C#/ Mono/Gtk#程序,它簡單地加載在窗口中放入的文件作爲Gdk.Pixbuf並顯示它們。如何在Windows中從Unicode文件名創建Gdk.Pixbuf?

它在Ubuntu上運行良好。但在Windows上,如果我嘗試使用非ASCII文件名(如C:\áéíóú.jpg)刪除文件,程序將崩潰。我認爲這是我的代碼第一個問題。所以我做了一個簡單的測試用例。

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

輸出

C:\áéíóú.jpg存在?真
GLib.GException:無法打開文件「C:\áéíóú.jpg」:沒有這樣的文件或目錄

事實證明,油嘴想不通的是存在的文件,是否存在。我不知道如何解決這個問題,以便我可以從一個Unicode文件名中將一個圖像文件加載到Windows上的Pixbuf中。

+0

您確定文件名字符串是UTF8編碼,並且磁盤上的文件名編碼也是UTF8嗎? – ptomato

+0

我不確定。當我執行drag'n'drop時,我閱讀Gtk +總是使用UTF-16編碼。因此,我將從drag'n'drop收到的數據編碼爲UTF-16。但是,如果我將文件名作爲命令行參數或通過Gtk文件打開對話框傳遞,我會得到相同的結果。如果您認爲通過Gtk獲得的文件名對於Gdk無效,那這很奇怪。 – OdraEncoded

+0

GTK從不使用UTF-16進行編碼。你一定看錯了。 GLib在內部使用UTF8,除了編碼文件名(在Windows上是UTF8),甚至通常在現代Unix上使用UTF8。 – ptomato

回答

2

這似乎是gtk-sharp < - > gdk-pixbuf互操作中的一個問題。

顯然,在除Windows以外的每個操作系統上,gdk_pixbuf_new_from_file都需要使用utf8編碼的文件名。然而,在Windows上,這個函數被重命名爲gdk_pixbuf_new_from_file_utf8,並被一個包含locale轉換的包裝所替代,並繼續調用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); 
} 

我已經成功測試了這一點。希望這可以幫助。

+0

謝謝!這解決了問題。我希望有一天Gtk#可以獲得類似於圖書館一部分的功能。 – OdraEncoded

相關問題