我有一个C#/ Mono / Gtk#程序,只需将窗口中丢弃的文件加载为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':没有这样的文件或目录
事实证明,Glib无法找出存在的文件。而且我不知道如何修复它以便我可以从Unicode文件名中将图像文件加载到Windows上的Pixbuf中。
答案 0 :(得分:2)
这似乎是gtk-sharp< - > gdk-pixbuf互操作中的一个问题。
显然在除Windows之外的每个操作系统上,gdk_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。因此,buggy构造函数中的代码可以复制,修复和隐藏在一些帮助方法中,例如:
[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);
}
我已成功测试了这一点。希望这会有所帮助。