2009-08-16 86 views
2

我的表單中有一個Groupbox裏面的圖片框,裏面有雷達圖片作爲背景圖片。我的意圖是在運行時動態加載雷達區域內的微小Jpeg圖像(疊加),但我不確定實現此目的的最佳方式。 歡迎所有瘋狂的想法(但我寧願容易做一些)。 謝謝大家。在C#中模擬雷達的最佳方法是什麼?

回答

3

這很大程度上取決於你的「雷達」需要的樣子,但幾乎可以肯定你需要實現Paint事件處理程序,並自己繪製雷達顯示的內容。一個圖片框只會讓你到目前爲止(「不太」)。

GDI +非常易於使用來繪製圓圈,線條,文本和圖像,並且可以完全控制顯示器的外觀。

0

最簡單的方法是將您的微型JPEG加載到微小的PictureBox中,並在運行時將它們添加到主PictureBox的Controls集合中(即將它們放置在PictureBox上)。

由於這可能會產生閃爍,稍微複雜一點的方法是將主圖片和微小圖片保存在類級別的Bitmap對象中,並在主PictureBox的Paint事件中複製主圖片,然後再複製每個小圖片圖片添加到使用DrawImage方法的第二個類級別的位圖(名爲_doubleBuffer或類似的東西),然後將_doubleBuffer複製到您的PictureBox(也使用DrawImage)。無論何時需要更新顯示並重新繪製所有內容,只需調用PictureBox的Invalidate方法即可。

這裏有很多關於SO的例子展示瞭如何使用這些方法。祝你好運,這聽起來很有趣(如果你正在重寫經典的街機遊戲Submarine,請告訴我 - 我喜歡那款遊戲)。

+0

該死!這聽起來很瘋狂......想想我會按照上面JW的建議去閱讀GDI +的初學者。謝謝。沒玩過潛艇;我更喜歡NES版的「尋找紅十月」。 – 2009-08-16 17:29:12

+0

這並不複雜,它實際上只是Jason的回答。我也在談論GDI +和處理Paint事件。 – MusiGenesis 2009-08-16 17:37:00

+0

雙緩衝部分對於避免閃爍是必不可少的。 – MusiGenesis 2009-08-16 17:37:35

2

至於實際的例子:

// Among others 
    using System.Collections.Generic; 
    using System.Drawing; 
    using System.IO; 

    class TinyPic { 
    public readonly Image Picture; 
    public readonly Rectangle Bounds; 

    public TinyPic(Image picture, int x, int y) { 
     Picture = picture; 
     Bounds = new Rectangle(x, y, picture.Width, picture.Height); 
    } 
    } 

    class MyForm : Form { 

    Dictionary<String, TinyPic> tinyPics = new Dictionary<String, TinyPic>(); 

    public MyForm(){ 
     InitializeComponent(); // assuming Panel myRadarBox 
          // with your background is there somewhere; 
     myRadarBox.Paint += new PaintEventHandler(OnPaintRadar); 
    } 

    void OnPaintRadar(Object sender, PaintEventArgs e){ 
     foreach(var item in tinyPics){ 
     TinyPic tp = item.Value; 
     e.Graphics.DrawImageUnscaled(tp.Picture, tp.Bounds.Location); 
     } 
    } 

    void AddPic(String path, int x, int y){ 
     if (File.Exists(path)){ 
     var tp = new TinyPic(Image.FromFile(path), x, y); 
     tinyPics[path] = tp; 
     myRadarBox.Invalidate(tp.Bounds); 
     } 
    } 

    void RemovePic(String path){ 
     TinyPic tp; 
     if (tinyPics.TryGetValue(path, out tp)){ 
     tinyPics.Remove(path); 
     tp.Picture.Dispose(); 
     myRadarBox.Invalidate(tp.Bounds); 
     } 
    } 
    } 

當然這是很基本的,假定圖像源的路徑,並沒有考慮許多複雜的東西照顧,但這是它的快速和骯髒的JIST你當然可以繼續發展。

+0

乾杯.....沒有完成GDI +或任何圖形pprogrammingin C#和迫近的最後期限(這是在我截止日期前在我<48前突然出現)這可以幫助.. – 2009-08-17 00:59:39

2

Click here運行一個示例應用程序,演示如何做雷達(或單向,至少)的基礎知識。注意:此應用程序不會執行雙緩衝或微小圖像的透明度。

該項目的源代碼是here

更新代碼:

public partial class Form1 : Form 
{ 
    private Bitmap _canvas; 
    private float _sweepStartAngle = -90; 
    private float _sweepAngle = 15; 
    private SolidBrush _sweepBrush = new SolidBrush(Color.Red); 
    private Rectangle _sweepRect; 
    private Timer _sweepTimer = new Timer(); 
    private Bitmap _submarine; 
    private Point _submarinePosition = new Point(0, 0); 
    private Random rnd = new Random(); 

    public Form1() 
    { 
     InitializeComponent(); 

     _canvas = new Bitmap(pbScope.Width, pbScope.Height); 
     pbScope.Image = _canvas; 
     _sweepRect = new Rectangle(0, 0, pbScope.Width, pbScope.Height); 

     _submarine = (Bitmap)pbSubmarine.Image; 

     RedrawScope(); 

     _sweepTimer.Interval = 100; 
     _sweepTimer.Tick += new EventHandler(_sweepTimer_Tick); 
     _sweepTimer.Start(); 
    } 

    void _sweepTimer_Tick(object sender, EventArgs e) 
    { 
     _sweepStartAngle += _sweepAngle; 
     RedrawScope(); 
    } 

    private void RedrawScope() 
    { 
     using (Graphics g = Graphics.FromImage(_canvas)) 
     { 
      // draw the background 
      g.DrawImage(pbBackground.Image, 0, 0); 

      // draw the "sweep" 
      GraphicsPath piepath = new GraphicsPath(); 
      piepath.AddPie(_sweepRect, _sweepStartAngle, _sweepAngle); 
      g.FillPath(_sweepBrush, piepath); 
      //g.FillPie(_sweepBrush, _sweepRect, _sweepStartAngle, _sweepAngle); 

      // move the submarine and draw it 
      _submarinePosition.X += rnd.Next(3); 
      _submarinePosition.Y += rnd.Next(3); 
      // check if submarine intersects with piepath 
      Rectangle rect = new Rectangle(_submarinePosition, _submarine.Size); 
      Region region = new Region(piepath); 
      region.Intersect(rect); 
      if (!region.IsEmpty(g)) 
      { 
       g.DrawImage(_submarine, _submarinePosition); 
      } 
     } 
     pbScope.Image = _canvas; 
    } 

    private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
    { 
     _sweepTimer.Stop(); 
     _sweepTimer.Dispose(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     //GraphicsPath piepath = new GraphicsPath(); 
     //piepath.AddPie(

    } 

} 

    private void InitializeComponent() 
    { 
     System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); 
     this.pbScope = new System.Windows.Forms.PictureBox(); 
     this.pbBackground = new System.Windows.Forms.PictureBox(); 
     this.pbSubmarine = new System.Windows.Forms.PictureBox(); 
     ((System.ComponentModel.ISupportInitialize)(this.pbScope)).BeginInit(); 
     ((System.ComponentModel.ISupportInitialize)(this.pbBackground)).BeginInit(); 
     ((System.ComponentModel.ISupportInitialize)(this.pbSubmarine)).BeginInit(); 
     this.SuspendLayout(); 
     // 
     // pbScope 
     // 
     this.pbScope.Location = new System.Drawing.Point(12, 12); 
     this.pbScope.Name = "pbScope"; 
     this.pbScope.Size = new System.Drawing.Size(300, 300); 
     this.pbScope.TabIndex = 0; 
     this.pbScope.TabStop = false; 
     // 
     // pbBackground 
     // 
     this.pbBackground.Image = ((System.Drawing.Image)(resources.GetObject("pbBackground.Image"))); 
     this.pbBackground.Location = new System.Drawing.Point(341, 12); 
     this.pbBackground.Name = "pbBackground"; 
     this.pbBackground.Size = new System.Drawing.Size(300, 300); 
     this.pbBackground.TabIndex = 1; 
     this.pbBackground.TabStop = false; 
     this.pbBackground.Visible = false; 
     // 
     // pbSubmarine 
     // 
     this.pbSubmarine.Image = ((System.Drawing.Image)(resources.GetObject("pbSubmarine.Image"))); 
     this.pbSubmarine.Location = new System.Drawing.Point(658, 45); 
     this.pbSubmarine.Name = "pbSubmarine"; 
     this.pbSubmarine.Size = new System.Drawing.Size(48, 48); 
     this.pbSubmarine.TabIndex = 2; 
     this.pbSubmarine.TabStop = false; 
     this.pbSubmarine.Visible = false; 
     // 
     // Form1 
     // 
     this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 
     this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 
     this.ClientSize = new System.Drawing.Size(326, 328); 
     this.Controls.Add(this.pbSubmarine); 
     this.Controls.Add(this.pbBackground); 
     this.Controls.Add(this.pbScope); 
     this.Name = "Form1"; 
     this.Text = "Radar"; 
     this.Load += new System.EventHandler(this.Form1_Load); 
     this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); 
     ((System.ComponentModel.ISupportInitialize)(this.pbScope)).EndInit(); 
     ((System.ComponentModel.ISupportInitialize)(this.pbBackground)).EndInit(); 
     ((System.ComponentModel.ISupportInitialize)(this.pbSubmarine)).EndInit(); 
     this.ResumeLayout(false); 

    } 
+0

你可以在代碼中編輯?今天的標準不僅僅需要外部鏈接。 – 2014-03-05 12:00:42

+0

當然,雖然發佈依賴於控件初始化和佈局等的代碼並不是非常實用 – MusiGenesis 2014-03-05 17:15:13

相關問題