2012-10-18 5 views
2

저는 Gdk.Pixbuf로 창에 떨어 뜨린 파일을로드하고 표시하는 C#/Mono/Gtk # 프로그램이 있습니다.Windows에서 유니 코드 파일 이름을 사용하여 Gdk.Pixbuf를 만드는 방법은 무엇입니까?

우분투에서는 잘 작동합니다. 그러나 Windows에서 C : \ ééíóú.jpg와 같은 ASCII 파일이 아닌 파일을 삭제하려고하면 프로그램이 중단됩니다. 내 코드가 처음에는 문제라고 생각했습니다. 그래서 간단한 테스트 케이스를 만들었습니다.

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

출력

C : \의 áéíóú.jpg가 존재? 진정한
GLib.GException ': \의 áéíóú.jpg C를'파일을 열지 못했습니다 그것이 나오는 것에 따라

이, 입심이 존재하는 파일을 알아낼 수 없습니다 그런 파일이나 디렉토리를, 존재한다. 그리고 유니 코드 파일 이름으로 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를 제외한 모든 OS에 분명히 gdk_pixbuf_new_from_file은 utf8로 인코딩 된 파일 이름을 사용합니다. 그러나 창에서이 함수는 gdk_pixbuf_new_from_file_utf8으로 이름이 바뀌고 로켈 변환을 수행하고 utf8 버전을 호출하는 래퍼로 대체됩니다. gtk-sharp는이 사실을 모르고 gdk_pixbuf_new_from_file utf8 인수를 사용하므로 Windows에서 예기치 않은 추가 로켈 변환으로 인해 파일 이름이 손상됩니다.

해결 방법 나는 파일 이름 대신 Stream을 사용하는 Pixbuf 생성자를 사용하도록 제안했지만 이미지가 제대로로드되지 않는다고 포스터가보고했습니다.

업데이트 : 다행히 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

관련 문제