我有一个 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 exists? True
GLib.GException: Failed to open file 'C:\áéíóú.jpg': No such file or directory
事实证明,Glib 无法判断文件是否存在。我不知道如何修复它,以便我可以将图像文件从 Unicode 文件名加载到 Windows 上的 Pixbuf 中。
最佳答案
这似乎是 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。因此,有缺陷的构造函数中的代码可以在某些辅助方法中进行复制、修复和隐藏,例如:
[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);
}
我已经测试成功了。希望这会有所帮助。
关于windows - 如何在 Windows 中从 Unicode 文件名创建 Gdk.Pixbuf?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12946991/