views:

8406

answers:

4

I am working on a Windows Forms application in VS 2008, and I want to display one image over the top of another, with the top image being a gif or something with transparent parts.

Basically I have a big image and I want to put a little image on top if it, so that they kinda appear as one image to the user.

I've been trying to use a picturebox, but this doesn't seem to have worked, any suggestions?

+2  A: 

Put the big/bottom image on a PictureBox, then add a handler to the OnPaint event and use one of the e.Graphics.DrawImage() overloads. You can load the image using Image.FromFile().

The small/top image will have to have an alpha channel and be transparent in the background for the overlay to work. You should be able to ensure this pretty easily in Photoshop or something similar. Make sure you save in a format that supports the alpha channel, such as PNG.

Jon Grant
A: 

I've always found that I've had to composite the images myself, using a single picturebox or control. Having two pictureboxes with transparent parts has never worked for me.

Charlie Salts
+7  A: 

I was in a similar situation a couple of days ago. You can create a transparent control to host your image.

public class TransparentControl : Control
{
    private readonly Timer refresher;
    private Image _image;

    public TransparentControl()
    {
        SetStyle(ControlStyles.SupportsTransparentBackColor, true);
        BackColor = Color.Transparent;
        refresher = new Timer();
        refresher.Tick += TimerOnTick;
        refresher.Interval = 50;
        refresher.Enabled = true;
        refresher.Start();
    }

    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x20;
            return cp;
        }
    }

    protected override void OnMove(EventArgs e)
    {
        RecreateHandle();
    }


    protected override void OnPaint(PaintEventArgs e)
    {
        if (_image != null)
        {
            e.Graphics.DrawImage(_image, (Width / 2) - (_image.Width / 2), (Height / 2) - (_image.Height / 2));
        }
    }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
       //Do not paint background
    }

    //Hack
    public void Redraw()
    {
        RecreateHandle();
    }

    private void TimerOnTick(object source, EventArgs e)
    {
        RecreateHandle();
        refresher.Stop();
    }

    public Image Image
    {
        get
        {
            return _image;
        }
        set
        {
            _image = value;
            RecreateHandle();
        }
    }
}
Leon Tayson
Whats the Hack for I don't see Redraw called internally. When does it need to be called?
Greg Dean
as you can see, it's Public. IIRC, i encountered a bug when resizing the form of an anchored TransparentControl. I think it disappears from the form, so I put that Redraw method to be called from the form's resize.
Leon Tayson
works great. The only problem I faced is that unlike the PictureBox, I couldnt set this to auto-resize or stretch. Other than that, it works like a charm. Thanks Leon!
silverCORE
What's the timer/Refresh for?
Cheeso
Set `ControlFlags.ResizeRedraw`.
SLaks