Florence
Florence

Reputation: 65

Transparent image over a control

I'm doing an application with a splash screen.

I've an image an I'd like to put below a progress bar like :

Example

Example

I've succeeded to make the bitmap transparent. But, now, the image is behind the progress bar

Now

Now

Is there a way to get the image in front of the progress bar ? Thank you. F.

Code :

public partial class Form1 : Form
{
    Bitmap m_l;
    public Form1()
    {
        InitializeComponent();

        m_l = Properties.Resources.LU;

        m_l.MakeTransparent(Color.Transparent);
    }

    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.DrawImage(m_l, new Rectangle(new Point(0, -40), new Size(200, 264))); progressBar1.Refresh();
    }
}

Upvotes: 3

Views: 1717

Answers (4)

Marcos
Marcos

Reputation: 97

as ways, people are developers but seams to have a really weak logic, post code and link the rest to a site that can die at any time, here the 2 missing line of the answer

public static System.Drawing.Drawing2D.GraphicsPath Transparent(Image im)  
    {  
        int x;  
        int y;  
        Bitmap bmp = new Bitmap(im);  
        System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();  
        Color mask = bmp.GetPixel(0, 0);  

        for (x = 0; x <= bmp.Width - 1; x++)  
        {  
            for (y = 0; y <= bmp.Height - 1; y++)  
            {  
                if (!bmp.GetPixel(x, y).Equals(mask))  
                {  
                    gp.AddRectangle(new Rectangle(x, y, 1, 1));  
                }  
            }  
        }  
        bmp.Dispose();  
        return gp;  

use:

System.Drawing.Drawing2D.GraphicsPath gp = Resources.Images.Transparent(pictureBox1.Image);  
pictureBox1.Region = new System.Drawing.Region(gp);  

Upvotes: 0

gunnerone
gunnerone

Reputation: 3572

You can accomplish this using a PictureBox with a Region.

Add a PictureBox to your form. This will hold the image. Position it to overlap the ProgressBar as you would like. Set the Image property to your overlay image.

In the form constructor we're then going to set the Region of this PictureBox. The region defines the shape of the control. We're going to set the Region equal to the non-transparent parts of the image.

public partial class Form1 : Form
{
  public Form1()
  {
    InitializeComponent();
    pictureBox1.Region = CreateRegion(Properties.Resources.LU);
  }

  private static Region CreateRegion(Bitmap maskImage)
  {
    // We're using pixel 0,0 as the "transparent" color.
    Color mask = maskImage.GetPixel(0, 0);
    GraphicsPath graphicsPath = new GraphicsPath();
    for (int x = 0; x < maskImage.Width; x++)
    {
      for (int y = 0; y < maskImage.Height; y++)
      {
        if (!maskImage.GetPixel(x, y).Equals(mask))
        {
          graphicsPath.AddRectangle(new Rectangle(x, y, 1, 1));
        }
      }
    }

    return new Region(graphicsPath);
  }
}

Screenshot of form

Much of this code came from here

Upvotes: 3

TaW
TaW

Reputation: 54433

There are 5 6 options:

  1. You could set the ProgressBar's BackColor to Transparent. Result:

enter image description here

Translation:

Invalid property value. This control does not support a transparent backcolor.

This will hold true for a subclass as well.

  1. You could nest a transparent Panel with the image as its BackgroundImage. Result:

enter image description here

As you can see, despite the panel and most of the image being transparent, the progressbar still underlays it with a rectangle in its own BackColor; which, see above, can't be transparent.

  1. You could overlay with the panel.

Result:

enter image description here

Looks similar. But this time the backcolor is the original background of wherever the panel was before overlaying it. This is the way winforms fakes transparency; this faked transpareny will only work with nested controls, but not with all..

  1. You could draw your image in the progressbar's Paint event. Problem: It doesn't have one. And if you subclass it it will not work for you.

To sum it up: all those attempts fail; the conclusion is simple: ProgressBar is an animated control that won't support any messing with it.

  1. Last option: Write your own. You can subclass a Panel or Label and write your own progressbar. Many folks who wanted to have a custom look, have done this and you can find many ready made examples.

Upate: Looks like you can have a 6th option, which will work if and only if you don't need semi-transparency, like anti-aliasing etc..: You can create a GraphicsPath to create a Region which will mask some control with the image.. So while my example will not work, OP's image may look quite OK.

Upvotes: 0

Rand Random
Rand Random

Reputation: 7440

(sorry, for missuing the answer function but the answer is to long for a comment)

@TaW seems like you didnt quite understand the approach, so I will try to explain it in more detail

OP asked if he can make a transparant Image over another control (a progressbar)

I assumed this transparent Image is inside a PictureBox, you seem to assume some other control

to position the control, if my assumption is correct the picturebox, infront of the progress bar all he has to do is right click and click "Bring to Front" on the PictureBox

and there you have it a "transparent" PictureBox infront of a progressbar - but as you mentioned in your answer we cannot stop there since the "transparent" isnt what I expected, but obviously you knew - its this "parent background color picking" that WinForms does and we end up with a not fully transparent image infront of the ProgressBar but instead one with a gray Background

Now the posted url comes in place: http://www.richardhyland.com/diary/2009/05/26/how-to-truely-make-a-picturebox-background-transparent/

This is the code provided, and explained in that url:

public static System.Drawing.Drawing2D.GraphicsPath Transparent(Image im)
{
    int x;
    int y;
    Bitmap bmp = new Bitmap(im);
    System.Drawing.Drawing2D.GraphicsPath gp = new System.Drawing.Drawing2D.GraphicsPath();
    Color mask = bmp.GetPixel(0, 0);

    for (x = 0; x <= bmp.Width - 1; x++)
    {
        for (y = 0; y <= bmp.Height - 1; y++)
        {
            if (!bmp.GetPixel(x, y).Equals(mask))
            {
                gp.AddRectangle(new Rectangle(x, y, 1, 1));
            }
        }
    }
    bmp.Dispose();
    return gp;
}

With this we can achieve a fully transparent Picture box infront of a Progress bar.

So without this Code, we have this:

But with that Code:

Notice, this approach has some downsides:

  1. doesn't work perfectly - as you can see gray pixels around the edges of the image
  2. performs poorly on big Images - since getting each pixel with GetPixel is "challange"

(Please, ignore the fact that the image shows "JPG" and I am talking about transparent Images - this was just the first image Google search presented me and yes, the file is a transparent png)

Upvotes: 3

Related Questions