How to make two transparent layer with c#?
If you need a control support transparency, you should override painting of the control and draw the control in this order:
- Draw all controls in the same container which are under your control (based on z-index) on a bitmap.
- Then draw that bitmap on graphics of your control.
- At last draw content of your control.
- Also the
BackColor
of your control should beColor.Transparent
.
Here is the result of creating TransparentLabel
and TransparentPictureBox
controls. In the below image, there is label, image, label, image and then label in order and as you can see picture boxes and labels has been rendered having transparent background and respecting the z-index:
Transparent Label
class TransparentLabel : Label
{
public TransparentLabel()
{
this.BackColor = Color.Transparent;
}
protected override void OnPaint(PaintEventArgs e)
{
if (Parent != null && this.BackColor == Color.Transparent)
{
using (var bmp = new Bitmap(Parent.Width, Parent.Height))
{
Parent.Controls.Cast<Control>()
.Where(c => Parent.Controls.GetChildIndex(c) > Parent.Controls.GetChildIndex(this))
.Where(c => c.Bounds.IntersectsWith(this.Bounds))
.OrderByDescending(c => Parent.Controls.GetChildIndex(c))
.ToList()
.ForEach(c => c.DrawToBitmap(bmp, c.Bounds));
e.Graphics.DrawImage(bmp, -Left, -Top);
}
}
base.OnPaint(e);
}
}
Transparent PictureBox
class TransparentPictureBox : PictureBox
{
public TransparentPictureBox()
{
this.BackColor = Color.Transparent;
}
protected override void OnPaint(PaintEventArgs e)
{
if (Parent != null && this.BackColor==Color.Transparent)
{
using (var bmp = new Bitmap(Parent.Width, Parent.Height))
{
Parent.Controls.Cast<Control>()
.Where(c => Parent.Controls.GetChildIndex(c) > Parent.Controls.GetChildIndex(this))
.Where(c => c.Bounds.IntersectsWith(this.Bounds))
.OrderByDescending(c => Parent.Controls.GetChildIndex(c))
.ToList()
.ForEach(c => c.DrawToBitmap(bmp, c.Bounds));
e.Graphics.DrawImage(bmp, -Left, -Top);
}
}
base.OnPaint(e);
}
}
Make Picture boxes transparent, each overlapping the other with a corner?
Transparency in winforms is kind of misleading, since it's not really transparency.
Winforms controls mimic transparency by painting the part of their parent control they would hide instead of their own background.
However, they will not paint the other controls that might be partially covered by them.
This is the reason your top most picture boxes hides your big picture box.
You can overcome this by creating a custom control that inherits from PictureBox
and override its OnPaintBackground
method (taken, with slight adjustments, from this code project article):
protected override void OnPaintBackground(PaintEventArgs e)
{
base.OnPaintBackground(e);
Graphics g = e.Graphics;
if (this.Parent != null)
{
var index = Parent.Controls.GetChildIndex(this);
for (var i = Parent.Controls.Count - 1; i > index; i--)
{
var c = Parent.Controls[i];
if (c.Bounds.IntersectsWith(Bounds) && c.Visible)
{
using (var bmp = new Bitmap(c.Width, c.Height, g))
{
c.DrawToBitmap(bmp, c.ClientRectangle);
g.TranslateTransform(c.Left - Left, c.Top - Top);
g.DrawImageUnscaled(bmp, Point.Empty);
g.TranslateTransform(Left - c.Left, Top - c.Top);
}
}
}
}
}
Microsoft have published a Knowledge base article to solve this problem a long time ago, however it's a bit out-dated and it's code sample is in VB.Net.
Another option is to paint the images yourself, without picture boxes to hold them, by using Graphics.DrawImage
method.
The best place to do it is probably in the OnPaint
method of the form.
How could I position multiple transparent PNGs onto a JPG using c# and asp.net?
Here's some code i use (modified to show the principle):
private void ProcessPhoto()
{
System.Drawing.Image imgThumb = System.Drawing.Image.FromFile("some.jpg");
// 43w, 35h = offset in frame
System.Drawing.Image imgFrame = System.Drawing.Image.FromFile("transparent_something.png");
Bitmap bmImage = new Bitmap(imgThumb);
bmImage.SetResolution(72, 72);
Graphics gFrame = Graphics.FromImage(imgFrame);
gFrame.DrawImage(bmImage, new Point(38, 44)); // offset point of where you want to draw
gFrame.Dispose();
SavePhoto(imgFrame, "dest.png");
imgFrame.Dispose();
imgThumb.Dispose();
}
private void SavePhoto(System.Drawing.Image img, string fileName)
{
string ext = Path.GetExtension(fileName);
fileName = fileName.Replace(ext, ".png");
img.Save(fileName, GetImageEncoder("PNG"), null);
}
Edit:
Read all about the Graphics class here
Add additional half-transparent layer on picturebox
The code would be similar to this:
private void pictureBox1_Paint (object sender, PaintEventArgs e)
{
using (SolidBrush b = new SolidBrush(Color.FromArgb(128, Color.White))
{
e.Graphics.FillRectangle (b, 0, 0, pictureBox1.Width, pictureBox1.Height);
}
However, the code above simply using a single color brush whose opactity is set to 128. There are other brush classes available, such as LinearGradientBrush
, TextureBrush
, PAthGradientBrush
and HatchBrush
.
Recommendation
To paint custom effects like you want to (for a button pressed state), a recommended approach would be to generate pre-rendered images that you can create either at runtime of your application or using an external program such as Adobe Photoshop and then save these images.
Then the painting code would simply take the image that represents the current state of your "button" and draw that image in the overriden pictureBox1_Paint
method.
This technique results in better graphics painting performance as opposed to simply repainting the same states at different state-change times in the application.
Combining two semi-transparent ellipses
edit: Sorry, there were a few errors with the properties of the various elements. This is tested:
Create a Path and put as Path.Data a GeometryGroup that has the two EllipseGeometries as child elements. Set GeometryGroup.FillRule to "EvenOdd" so that the area that both ellipses cover is not filled, and set "Fill" to the color you want the ellipses to have (here: AliceBlue).
Put that Path into a Control with "Background" property, like Border, and set that Background to the color you want the area both ellipses are covering to be (here: yellow).
Then you set Clip to the same GeometryGroup with FillRule set to "Nonzero" to prevent the area around the ellipses to also be painted with the background color.
<Border Background="Yellow">
<Path Fill="AliceBlue" Stroke="Black" StrokeThickness="4">
<Path.Data>
<GeometryGroup FillRule="EvenOdd">
<EllipseGeometry Center="100,100" RadiusX="40" RadiusY="80" />
<EllipseGeometry Center="100,100" RadiusX="80" RadiusY="40" />
</GeometryGroup>
</Path.Data>
</Path>
<Border.Clip>
<GeometryGroup FillRule="Nonzero">
<EllipseGeometry Center="100,100" RadiusX="40" RadiusY="80" />
<EllipseGeometry Center="100,100" RadiusX="80" RadiusY="40" />
</GeometryGroup>
</Border.Clip>
</Border>
If you need both ellipses to be painted in different colors use two Border and Path objects, use the same GeometryGroup with "EvenOdd" and set each of Border.Clip to one EllipseGeometry object.
If you need a more detailed definition use a PathGeometry instead of GeometryGroup and define the area with ArcSegments.
How to layer one window on top of another with transparency(Overlay) or how to do aplha-blending on two windows using directx?
Finally I found an answer myself. Further research lead me to This,This thread which was exactly what i was looking for. This might be useful to someone else and might save a lot of head banging on research.
Related Topics
How to Delete Cookies from Windows.Form
How to Deserialize a Complex JSON Object in C# .Net
Why Switch for Enum Accepts Implicit Conversion to 0 But No for Any Other Integer
Which Is Better, Return Value or Out Parameter
Managing Multiple Selections with Mvvm
How to Set the Timeout for a Tcpclient
Relocating App.Config File to a Custom Path
Is It Worthwhile to Initialize the Collection Size of a List<T> If It's Size Reasonably Known
External VS2013 Build Error "Error Msb4019: the Imported Project <Path> Was Not Found"
How to Store Int[] Array in Application Settings
The Server Committed a Protocol Violation. Section=Responsestatusline Error
How to Mock Non Virtual Methods
Property(With No Extra Processing) VS Public Field
How to Use Mvvmlight Simpleioc
What Does {0} Mean When Found in a String in C#
How to Fix a .Net Windows Application Crashing at Startup with Exception Code: 0Xe0434352