2017-02-13 35 views
-1

我有我自己的簡單3d引擎類(myGraphics),它將結果保存在Bitmap變量中。 然後,該位圖被放置在一個圖片框(PictureBox.Image = myGraphics.bmp如何在WindowsForms Picturebox上繪製字符串?

這是行之有效的,問題出現時,我需要在繪圖上標記一些點。由於沒有內置的在位圖上繪製字符串的方法,因此我在類似問題中遵循瞭解決方案,現在我在myGraphics上得到了一個Graphics變量,因此我可以在那裏繪製數字。有代碼的重要位如下:

public class myGraphics 
{ 
    public Graphics g; 
    public void initialize(int W, int H) 
    { 
     //sets some values 
     g = Graphics.FromImage(bmp); 
     g.SmoothingMode = SmoothingMode.AntiAlias; 
     g.InterpolationMode = InterpolationMode.HighQualityBicubic; 
     g.PixelOffsetMode = PixelOffsetMode.HighQuality; 
    } 
    public void draw() 
    { 
     // code to draw on myGraphics.bmp 
     markpoints(); 
    } 
    public void markpoints() 
    { 
     if (draw_points) { 
      foreach (objecto ob in solidos) { 
       for (int p = 0; p < ob.viewpoints.Count; p++) 
       { 
        // determine position of text (x, y) 
        SolidBrush drawBrush = new SolidBrush(Color.Black); 
        g.DrawString(p.ToString(), new Font("Arial", 10), drawBrush, x, y); 
        g.Flush(); 
       } 
      } 
     } 
    } 

現在,如果我這樣做是正確,g.Flush()應在合併位圖圖形克,但它不工作這樣,所以我得到的正確的形象,但沒有蜇傷它。

我也試過這樣:myGraphics.g = PictureBox.CreateGraphics();來解決它。在調試模式下使用斷點時,我意識到字符串確實出現在使用此方法的控件上,但在PictureBox更新後立即被擦除。

所以,我怎麼能解決這個問題,這樣我就可以在圖紙上顯示的數字?

+0

要修改的位圖,但沒有任何辦法,該圖片框就可以知道這一點。 Image類沒有事件。所以它不知道它需要重新繪製圖像。現在知道,您可以調用PictureBox的Invalidate()方法。 –

+0

這不是問題,但它使我得到它,所以謝謝。這是一個愚蠢的錯誤,我仍然會寫一個答案 –

回答

-2

PictureBox.Image更新,圖形將被清除。因此,markpoints()必須從課外調用,之後PictureBox.Image被更新。

而且,分配myGraphics.g = Picturebox.CreateGraphics()不會工作,對myGraphics.g變化不會被更新,以控制圖片框。控制的圖形必須在油漆事件進行更新,傳遞e.graphicsmarkpoints

此外,g.flush()不會合並圖形與位圖,它是該代碼實際上不必要

所以,最終的解決方案:

public class myGraphics 
{ 
    // public Graphics g is no longer necessary 
    public void initialize(int W, int H) { //sets some values} 
    public void draw() { // code to draw on myGraphics.bmp } 

    public void markpoints(Graphics graph) 
    { 
     if (draw_points) { 
      graph.SmoothingMode = SmoothingMode.AntiAlias; 
      graph.InterpolationMode = InterpolationMode.HighQualityBicubic; 
      graph.PixelOffsetMode = PixelOffsetMode.HighQuality; 

      foreach (objecto ob in solidos) { 
       for (int p = 0; p < ob.viewpoints.Count; p++) 
       { 
        // determine position of text (x, y) 
        SolidBrush drawBrush = new SolidBrush(Color.Black); 
        g.DrawString(p.ToString(), new Font("Arial", 10), drawBrush, x, y); 
       } 
      } 
     } 
    } 
} 

// Connect to picture box 
myGraphics mg = new myGraphics() 
Picturebox.Image = mg.bmp; 
PictureBox.Invalidate(); // forces update of the control using paint event 

private void PictureBox_Paint(object sender, PaintEventArgs e) 
{ 
    mg.markpoints(e.Graphics); 
} 
+1

_使用PictureBox.CreateGraphics()的方法足以解決問題_不,最有可能它是不夠的,因爲結果將不會持續..要麼繪製到圖像或使用Paint事件中的e.Graphics對象。 – TaW

+0

@TaW我不能分配'e.Graphics()= myGraphics.g',因爲'e.Graphics'是隻讀的......這是否意味着我必須將'markpoints()'代碼放在繪製事件中? –

+0

是的。或者,您可以將'e.Graphics'對象傳遞給使用它來執行繪圖的函數,例如'markpoints(e.Graphics)'。但請注意,這必須從'Paint'事件中調用,並且不允許存儲或緩存它,否則它將無效! – TaW