views:

699

answers:

5

I have a Picture box inside a Groupbox in my form with the Picture of a radar set as the background picture. My intention is to dynamically load tiny Jpeg images within the radar area (overlaid) at runtime but I am unsure as to the best way to achieve this. All crazy ideas welcomed (but I would prefer sane easy to do ones). Thank you all.

+3  A: 

It depends a lot on what your "radar" needs to look like, but almost certainly you'll need to implement the Paint event handler, and draw the contents of the radar display yourself. A picture box will only get you so far ("not very").

GDI+ is very easy to use to draw circles, lines, text, and images, and will give you complete control over how your display looks.

Jason Williams
A: 

The simplest way is to load your tiny JPEGs into tiny PictureBoxes, and add them to the main PictureBox's Controls collection (i.e. place them on the PictureBox) at runtime.

Since this will probably produce flicker, the slightly more complex way is to keep the main picture and the tiny pictures in class-level Bitmap objects, and in the main PictureBox's Paint event, you copy the main picture followed by each tiny picture onto a second class-level Bitmap (named _doubleBuffer or something like that) using the DrawImage method, and then copy _doubleBuffer onto your PictureBox (also using DrawImage). Whenever you need to update your display and redraw everything, you just call the PictureBox's Invalidate method.

There are loads of examples here on SO that show how to use these methods. Good luck, it sounds fun (if you're rewriting the classic arcade game Submarine, let me know - I loved that game).

MusiGenesis
Damn!! That sounds Crazy complicated... Think I'll go read up on GDI+ for beginners as suggested by JW above. thanks though. Didn't play Submarine; I'm more going for The NES version of "The Hunt for The Red October".
Dark Star1
It's not crazy complicated, and it's actually just an elaboration of Jason's answer. I'm also talking about GDI+ and handling the Paint event.
MusiGenesis
The double-buffering part is essential for avoiding flicker.
MusiGenesis
Why do I need to double buffer when the Radar Image is set as my main picturebox's background image. I was thinking of drawing a container (a panel in this case) whithin the draw area, making it invisible then create a rectf and set its boundaries to the container and draw within the rectf object boundaries... What'd you think of that scenario?
Dark Star1
You'll get flicker - trust me on this one. It's complicated, but flicker basically comes from GDI+ drawing operations getting "caught" in the middle of your monitor's refresh (along with other problems). The only way to avoid this is to do all your complicated multi-step drawing operations on a canvas that is not visible, and then rendering this canvas to the visible surface all at once.
MusiGenesis
Try out your approach - this will help you learn the basics of GDI+ (which are the same no matter what surface you're drawing on). It's relatively easy to make your code double-buffered after you've written the essential drawing stuff.
MusiGenesis
Ok I'm having some major problems with the way you told me. I have managed to define a Pie region within my main Picturebox (the picture pox has my radar image set as it's Background) but I have no way to add the little tiny images without distorting them.
Dark Star1
@dark-star1: not sure what you mean by distorting, but I'm guessing you mean they're being stretched and/or shortened. Are you rendering them onto your picture box using the DrawImage method? There are 30 overloads of this method, and depending on which one you use and how you use it, the tiny images may not be drawn where and how you want them drawn. Your best bet is to come up with a small code sample that demonstrates the problem, and post it here as another question. I would guess that I wouldn't even be able to answer it before someone else does. :)
MusiGenesis
Yes, the image is being blown out of proportion and I have used the DrawImage and DrawImageUnscaled methods.
Dark Star1
a link to the code: http://stackoverflow.com/questions/1319649/how-do-i-display-an-image-within-a-region-defined-in-a-picturebox
Dark Star1
@dark-star1: I'm not sure what your Pie region is exactly, but it's possible to set up Transforms in GDI that take the normal x/y coordinate system and distort it in some way, and (based on another question of yours I saw) that may be what's happening here. Normally, if you use a DrawImage overload that uses DrawMode.Pixel, the tiny image should be rendered exactly as it is. Again, without a code sample I'm flying blind here.
MusiGenesis
My pie region is just a semi circle overlay on top of my radar background, which is this image: http://www.aefreemart.com/2006/06/animating-radar-screen.html cut in half (horizontally of course) :)
Dark Star1
+2  A: 

As for actual example:

  // 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);
      }
    }
  }

This of course is very basic, assumes image source is path and doesn't take care of many intricate things, but that's the quick and dirty jist of it which you can certainly build on.

Cheers..... Having not done GDI+ or any graphics pprogrammingin C# and a Deadline looming (This was sprung on me <48 before deadline) This could help..
Dark Star1
+1  A: 

Click here to run a sample application that demonstrates the basics of how to do radar (or one way, at least). Note: this application does not do double-buffering or transparency of the tiny image.

Source code for the project is here.

MusiGenesis
A: 

anyone have any idea how to program the line and sweeping it using C#? Please email me at [email protected]. I used GDI to draw some circles and lines to create my own radar but i still cant seem to create the sweep line. Anyone has a simple way of creating it because i am new to C# thanks.