我的表單中有一個Groupbox裏面的圖片框,裏面有雷達圖片作爲背景圖片。我的意圖是在運行時動態加載雷達區域內的微小Jpeg圖像(疊加),但我不確定實現此目的的最佳方式。 歡迎所有瘋狂的想法(但我寧願容易做一些)。 謝謝大家。在C#中模擬雷達的最佳方法是什麼?
回答
這很大程度上取決於你的「雷達」需要的樣子,但幾乎可以肯定你需要實現Paint事件處理程序,並自己繪製雷達顯示的內容。一個圖片框只會讓你到目前爲止(「不太」)。
GDI +非常易於使用來繪製圓圈,線條,文本和圖像,並且可以完全控制顯示器的外觀。
最簡單的方法是將您的微型JPEG加載到微小的PictureBox中,並在運行時將它們添加到主PictureBox的Controls集合中(即將它們放置在PictureBox上)。
由於這可能會產生閃爍,稍微複雜一點的方法是將主圖片和微小圖片保存在類級別的Bitmap對象中,並在主PictureBox的Paint事件中複製主圖片,然後再複製每個小圖片圖片添加到使用DrawImage方法的第二個類級別的位圖(名爲_doubleBuffer或類似的東西),然後將_doubleBuffer複製到您的PictureBox(也使用DrawImage)。無論何時需要更新顯示並重新繪製所有內容,只需調用PictureBox的Invalidate方法即可。
這裏有很多關於SO的例子展示瞭如何使用這些方法。祝你好運,這聽起來很有趣(如果你正在重寫經典的街機遊戲Submarine,請告訴我 - 我喜歡那款遊戲)。
至於實際的例子:
// 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你當然可以繼續發展。
乾杯.....沒有完成GDI +或任何圖形pprogrammingin C#和迫近的最後期限(這是在我截止日期前在我<48前突然出現)這可以幫助.. – 2009-08-17 00:59:39
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);
}
你可以在代碼中編輯?今天的標準不僅僅需要外部鏈接。 – 2014-03-05 12:00:42
當然,雖然發佈依賴於控件初始化和佈局等的代碼並不是非常實用 – MusiGenesis 2014-03-05 17:15:13
- 1. 什麼是模擬JUnit構造函數的最佳方法?
- 2. 模擬多部分問題的最佳方法是什麼
- 3. 在ruby中模擬第三方對象的最佳方法是什麼?
- 4. 在Grails中建模地圖值的最佳方法是什麼?
- 5. 在C++中處理大數字的最佳方法是什麼?
- 6. 在C++中檢查代理的最佳方法是什麼?
- 7. 在C++中標記字符串的最佳方法是什麼?
- 8. 在C#.NET中保存cookie的最佳方法是什麼?
- 9. 在C#中評估sql語句的最佳方法是什麼?
- 10. 在ASP.NET 3.5/C#中解析XML的最佳方法是什麼?
- 11. 在C中重置char []的最佳方法是什麼?
- 12. 模擬XAML代碼繼承的最佳方式是什麼?
- 13. Rails:模擬這個has_and_belongs_to_many協會的最佳方式是什麼
- 14. 在HTML textarea上模擬HTML輸入「maxlength」屬性的最佳方法是什麼?
- 15. 在Linux上爲Ruboto設置Android模擬器的最佳方法是什麼?
- 16. 模仿c#中findstr功能的最佳方式是什麼?
- 17. 將數據存儲在objective-c模型中的最佳方法是什麼?
- 18. ANTLR4的最佳方法是什麼?
- 19. 評論的最佳方法是什麼?
- 20. 用C學習GLADE的最佳/最快方法是什麼?
- 21. 模擬複雜的生產Web開發環境的最佳方法是什麼?
- 22. 驗證C#中readline輸入的最佳方法是什麼?
- 23. 實現雷達模擬
- 24. 在C#中模擬Python的「in」關鍵字功能的最佳方法是什麼?
- 25. 在HTML中模擬水平XAML StackPanel的最佳方式是什麼?
- 26. 什麼是在網頁中模擬DOS或終端屏幕的最佳方式?
- 27. 模擬域的最佳方法?
- 28. 模擬WAN網絡的最佳方法
- 29. 數據庫:模擬這些需求的最佳方法是什麼?
- 30. 執行數學表達式的最佳方法是什麼?
該死!這聽起來很瘋狂......想想我會按照上面JW的建議去閱讀GDI +的初學者。謝謝。沒玩過潛艇;我更喜歡NES版的「尋找紅十月」。 – 2009-08-16 17:29:12
這並不複雜,它實際上只是Jason的回答。我也在談論GDI +和處理Paint事件。 – MusiGenesis 2009-08-16 17:37:00
雙緩衝部分對於避免閃爍是必不可少的。 – MusiGenesis 2009-08-16 17:37:35