2017-04-20 78 views
2

我正在嘗試創建一個小應用程序,該應用程序顯示您在文件選擇器中選擇的圖像。它應該在用戶調整窗口大小時調整大小。如何在Vala中將圖像調整爲窗口大小

我的應用程序工作到我將這段代碼添加到我的類的構造函數,應該讓圖像調整窗口大小時調整大小的能力。

window.size_allocate.connect(() => { 

     resize_image(); //<-- a problem 

    }); 

這個「應該」調用的方法resize_image當窗口改變其大小,但每次我添加此代碼,關於這一點我運行的基本操作系統崩潰,我的虛擬機停止工作(我必須重新啓動每次我嘗試運行我的程序)。

方法resize_image()的工作原理如下:(我知道我調整大小「alogrithm」心不是最好的,但是我只是用於測試此方法)

public void resize_image() 
{ 
    try 
    {  if(buf.get_width() < window.get_allocated_width()){ 
      buf = buf.scale_simple(window.get_allocated_width(), window.get_allocated_width(), Gdk.InterpType.NEAREST); 
      image.set_from_pixbuf(buf); 
      }  
    }catch(Error e) 
    { 
    } 
} 

現在我的問題: 爲什麼我的程序崩潰?從pixbuf到圖像的轉換是否對用戶來說太慢? 是否有另一種方法來調整圖像的窗口大小?

任何幫助,將不勝感激:)

回答

1

這裏的竅門是添加布局和設置的調整回調不窗口,但佈局。這不是完美的,它有點骯髒,但工作。初始定位工作不好,但有改進的空間。 必須檢查Gtk.Widget和Gtk.Containers的請求,分配和自然大小,甚至使用Gdk方法。遲到了,希望這會讓你朝正確的方向發展。

PS:我使用的是endless.png圖片,但可以隨意使用另一個圖片,只需更改代碼以反映它即可。

using Gtk; 

public int main (string[] args) { 
    Gtk.Image image; 
    Gtk.Layout layout; 
    Gtk.Window window; 
    Gdk.Pixbuf pixbuf; 

    Gtk.init (ref args); 

    window = new Gtk.Window(); 
    layout = new Gtk.Layout(); 
    image = new Gtk.Image(); 

    try { 
     pixbuf = new Gdk.Pixbuf.from_file ("endless.png"); 
     image = new Gtk.Image.from_pixbuf (pixbuf); 
     layout.put (image, 0,0); 
     window.add (layout); 

     layout.size_allocate.connect ((allocation) => { 
      print ("Width: %d Height: %d\n", allocation.width, allocation.height); 
      var pxb = pixbuf.scale_simple (allocation.width, allocation.height, Gdk.InterpType.BILINEAR); 
      image.set_from_pixbuf (pxb); 
     }); 

     window.destroy.connect (Gtk.main_quit); 

     window.show_all(); 

     Gtk.main(); 

     return 0; 
    } catch (Error e) { 
     stderr.printf ("Could not load file...exit (%s)\n", e.message); 
     return 1; 
    } 
} 

編輯

一個簡單的開羅版本:

using Gtk; 
using Cairo; 

public int main (string[] args) { 
    Cairo.ImageSurface image; 

    image = new Cairo.ImageSurface.from_png ("endless.png"); 

    Gtk.init (ref args); 

    var window = new Gtk.Window(); 
    var darea = new DrawingArea(); 
    window.add (darea); 
    window.show_all(); 

    darea.draw.connect ((cr) => { 
     float xscale; 
     float yscale; 

     cr.save(); 

     xscale = (float) darea.get_allocated_width()/image.get_width(); 
     yscale = (float) darea.get_allocated_height()/image.get_height(); 

     cr.scale (xscale, yscale); 
     cr.set_source_surface (image, 0, 0); 
     cr.paint(); 

     cr.restore(); 
     return true; 
    }); 

    window.destroy.connect (Gtk.main_quit); 

    Gtk.main(); 

    return 0; 
} 

編輯2: 我已經創造了另一個版本2個圖像之間進行切換,並檢查,而這樣做很多次,並檢查內存是否增加,但事實並非如此。添加了幾個框,並添加了2個按鈕。

using Gtk; 
using Cairo; 

public int main (string[] args) { 
    Cairo.ImageSurface image; 

    image = new Cairo.ImageSurface.from_png ("endless.png"); 

    Gtk.init (ref args); 

    var window = new Gtk.Window(); 
    var box1 = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); 
    var box2 = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); 
    var b1  = new Gtk.Button.with_label ("Image1"); 
    var b2  = new Gtk.Button.with_label ("Image2"); 
    box2.pack_start (b1, true, true, 0); 
    box2.pack_end (b2, true, true, 0); 
    var darea = new DrawingArea(); 
    box1.pack_start (box2, false, false, 0); 
    box1.pack_end (darea, true, true, 0); 
    window.add (box1); 
    window.show_all(); 

    b1.clicked.connect (() => { 
     image = new Cairo.ImageSurface.from_png ("endless.png"); 
     darea.queue_draw(); 
    }); 

    b2.clicked.connect (() => { 
     image = new Cairo.ImageSurface.from_png ("Gnome-logo.png"); 
     darea.queue_draw(); 
    }); 

    darea.draw.connect ((cr) => { 
     float xscale; 
     float yscale; 

     cr.save(); 

     xscale = (float) darea.get_allocated_width()/image.get_width(); 
     yscale = (float) darea.get_allocated_height()/image.get_height(); 

     cr.scale (xscale, yscale); 
     cr.set_source_surface (image, 0, 0); 
     cr.paint(); 

     cr.restore(); 
     return true; 
    }); 

    window.destroy.connect (Gtk.main_quit); 

    Gtk.main(); 

    return 0; 
} 
+0

非常感謝你:)但我有一個問題:你爲什麼說這是一個骯髒的方式?如果你有時間可以簡單地解釋如何以正確的方式來做到這一點? – guardian

+0

@guardian sry剛剛閱讀你的評論。那麼,不是很髒,但不反映最好的辦法。一個好主意是從[eog(gnome的眼睛,默認圖像查看器)](https://github.com/GNOME/eog)檢查代碼。另一個方法是創建一個基於繪圖區域的圖像視圖控件,並讓開羅,例如,調整大小和繪製圖像。有幾個問題。當然,這個工作可以改進。在過去,我已經實施了這樣的事情,甚至是專業的,並且很有效。 –

+0

另外請注意,我保留原來的pixbuf並從那裏調整大小。從圖像中檢索pixbuf會增加累積的重採樣損失,並且圖像質量會降低。 –