2011-03-31 45 views
3

我在單聲道gtk#中創建一個小的繪圖程序,並使用Cairo圖形庫。我在MacOs X系統上進行編碼和編譯。我有一個可繪製的對象,我在某個時間將它放入Pixbuf中,然後稍後將其檢索到可繪製對象中!這個想法是對drawable中的圖像進行「快照」,然後在其上繪製。gdk.Pixbuf在gtk中的問題#單聲道

問題是,當我將Pixbuf放回到drawable中時,它看起來模糊不清,所有帶有條紋的黃色,它看起來像是圖像的一部分缺失。

更新:我運行在我的Linux和Windows機器上的程序,它在那裏工作完美無瑕!所以這個誤差僅爲MacOS X上 下面的代碼:

// use: gmcs -pkg:gtk-sharp-2.0 -pkg:mono-cairo ttv1.cs 

using Gtk; 
using Cairo; 
using System; 

public class Draw : Window 
{ 
DrawingArea canvas; 

public Gdk.Pixbuf pixbuf; 

public Draw() : base("teikniteink") 
{ 
    canvas = new DrawingArea(); 
    canvas.ExposeEvent += canvasExposed; 
    DeleteEvent += delegate { Application.Quit();}; 

    KeyPressEvent += onKey; 
    SetDefaultSize(400,400); 
    SetPosition(WindowPosition.Center); 
    Add(canvas); 
    ShowAll(); 
} 


private void onKey(object o, KeyPressEventArgs args) 
{ 
    switch (args.Event.Key) 
    { 
     case Gdk.Key.w: 
     Console.WriteLine("Key Pressed {0}", args.Event.Key); 
     // Send to Pixbuf 
     pixbuf = Gdk.Pixbuf.FromDrawable(canvas.GdkWindow, Gdk.Colormap.System,0,0,0,0,400,400); 
     // Save to output.png 
        pixbuf.Save ("output.png", "png"); 
     break; 
     case Gdk.Key.e: 
     Console.WriteLine("Key Pressed {0}", args.Event.Key); 

     Gdk.GC g = new Gdk.GC(canvas.GdkWindow); 
     // Retrive from pixbuf 
     canvas.GdkWindow.DrawPixbuf (g,pixbuf,0,0,0,0,-1,-1,Gdk.RgbDither.Normal,0,0);  
     break; 
    } 
} 

private void canvasExposed(object o, ExposeEventArgs args) 
{ 
    using (Cairo.Context ctx = Gdk.CairoHelper.Create(canvas.GdkWindow)) 
    { 
     PointD start = new PointD(100,100); 
     PointD end = new PointD(300,300); 
     double width = Math.Abs(start.X - end.X); 
     double height = Math.Abs(start.Y - end.Y); 
     double xcenter = start.X + (end.X - start.X)/2.0; 
     double ycenter = start.Y + (end.Y - start.Y)/2.0; 

     ctx.Save(); 
     ctx.Translate(xcenter, ycenter); 
     ctx.Scale(width/2.0, height/2.0); 
     ctx.Arc(0.0, 0.0, 1.0, 0.0, 2*Math.PI); 
     ctx.Restore(); 
     ctx.Stroke(); 
    } 
} 

public static void Main() 
{ 
    Application.Init(); 
    new Draw(); 
    Application.Run(); 
} 
} 

它將如果有人知道什麼怎麼回事,可以點我在正確的方向來解決它是非常讚賞。

+0

這聽起來像你可能採取了錯誤的方法,但我不能確定;你試圖達到的最終目標是什麼? – ptomato 2011-03-31 09:08:24

+0

@ptomato目標是做一個簡單的塗鴉程序!用戶可以在上面繪製矩形,線條和圓圈,然後保存圖像(並加載圖像)。我打算在onMouseRelease事件上設置pixbuf,並從pixbuf讀取exposeEvent上的drawable,以便用戶將當前繪製的內容顯示在圖像頂部。我是gtk和cairo的新手,所以我可能會像你說的那樣採取錯誤的方法! – 2011-03-31 10:53:21

+0

如果你在其他平臺上運行它,它的工作原理肯定是GTK#的OS X端口中的一個錯誤。你應該在bugzilla.gnome.org上提交一個錯誤。 – ptomato 2011-03-31 13:08:44

回答

1

引發我以這種方式同樣的問題:

gw = gtk_widget_get_window(GTK_WIDGET(GLOBALS->mainwindow)); 
if(gw) 
    {  
    gdk_drawable_get_size(gw, &w, &h); 
    cm = gdk_drawable_get_colormap(gw); 
    if(cm) 
      { 
      dest = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, w, h); 
      if(dest) 
        { 
        dest2 = gdk_pixbuf_get_from_drawable(dest, gw, cm, 0, 0, 0, 0, w, h); 
        if(dest2) 
          { 
          succ = gdk_pixbuf_save (dest2, *GLOBALS->fileselbox_text, "png", &err, NULL); 
          } 
        } 
      } 
    } 

當源繪製的是石英窗口gdk_pixbuf_get_from_drawable()函數有問題,特別是在_gdk_quartz_image_copy_to_image()服務如何吧。總之,256位垂直條被轉換,但轉換程序假定像素是24位RGB而不是32位RGBA。下面的補丁固定我的問題:

--- gtk+/gdk/quartz/gdkimage-quartz.c 2011-12-03 14:24:03.000000000 -0600 
+++ gtk+664894/gdk/quartz/gdkimage-quartz.c  2013-10-15 18:52:24.000000000 -0500 
@@ -150,6 +150,10 @@ _gdk_quartz_image_copy_to_image (GdkDraw 
     data = [rep bitmapData]; 
     size = [rep size]; 

+  int bpr = [rep bytesPerRow]; 
+  int wid = size.width; 
+  int bpx = bpr/wid; 
+ 
     for (y = 0; y < size.height; y++) 
     { 
     guchar *src = data + y * [rep bytesPerRow]; 
@@ -158,12 +162,15 @@ _gdk_quartz_image_copy_to_image (GdkDraw 
      { 
       gint32 pixel; 

+    if (bpx == 4) // fix gdk_pixbuf_get_from_drawable "yellow stripes" 
+    pixel = src[0] << 16 | src[1] << 8 | src[2]; 
+    else 
       if (image->byte_order == GDK_LSB_FIRST) 
       pixel = src[0] << 8 | src[1] << 16 |src[2] << 24; 
       else 
       pixel = src[0] << 16 | src[1] << 8 |src[2]; 

-    src += 3; 
+    src += bpx; 

       gdk_image_put_pixel (image, dest_x + x, dest_y + y, pixel); 
      } 

我不知道這是否是固定在GTK OSX源的未來版本。我用我自己的方法來生成gtkwave的二進制文件,因爲我有一些必要的補丁,很久以前似乎從未集成到jhbuild源代碼樹中。

-Tony