c# overlay an image on top of another - c#

i am currently trying to put the notes on top of the staff image. However, the notes background are being set to the form background as shown in the image.
image type used is png.
//class music staff
public MusicStaff(int xLoc, int yLoc, int xSize, int ySize)
{
this.SetBounds(xLoc, yLoc, xSize, ySize);
this.Visible = true;
ResourceManager rm = Resources.ResourceManager;
Bitmap bmp = (Bitmap)rm.GetObject("Staff1");
this.BackgroundImage = bmp;
this.BackgroundImageLayout = ImageLayout.Stretch;
this.BackColor = Color.White;
//adding the background pic
panel4 = new MusicStaff(3, 62, 927, 150);
//adding a note
MusicNote p = new MusicNote(pitch, duration, shape, s);
p.SizeMode = PictureBoxSizeMode.StretchImage;
p.BackColor = Color.Transparent;
p.Size = new Size(50, 75);
p.Location = new Point(xCounter + starterX, NoteLocations.c0.mainPoint);
Bitmap myImage = (Bitmap)rm.GetObject(shape);
p.Image = myImage;

You are not really overlaying images. You are overlaying controls with images.
For this to work with transparency, your notes controls need to be nested in the staff control!
As they aren't, the transparency shows the color of their actualy parent, i.e. the form.
Set p.Parent=panel4 and adapt the locations accordingly, i.e. make them relative to the staff..
This is a limitation of winforms transparency, which doesn't support overlapping controls. Nested controls will work fine but only by faking the transparent parts by copying them from the parent..
Note that as a consequence you will not be able to have the notes overlap each other or be overlapped by any other controls.
Often giving up on using controls is the better way; instead one can simply draw all parts that make up the total..
So you could do a series of e.Graphics.DrawImage(noteImg, x, y) in the panel4_Paint event.

Related

Winforms Label on top of gif

I want to place a Label on top of a gif inside a PictureBox in winforms.
The problem ist that the label has a white background. I want it to be transparent.
My Code is as follows:
this.pictureBox = new PictureBox();
this.pictureBox.Image = Image.FromFile("my_background.gif");
this.pictureBox.Dock = DockStyle.Fill;
this.pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
this.label = new Label();
this.label.Text = "Hallo";
this.label.BackColor = Color.Transparent;
this.label.Location = new System.Drawing.Point(100, 100);
this.Controls.Add(this.label);
this.Controls.Add(this.pictureBox);
My problem is that the Label has a white Background even though the background is set to transparent. The solution for other having a similar problem was setting the parent of the label to the picture Box like this:
this.label.parent = this.pictureBox;
But that didn't solve the problem for me. Is there any other way to achieve this?
Thanks for any answers.
Thanks for the hint.
It worked fine when putting only a view controls in front of the gif. When adding to many it got very buggy and only some rectangular parts of the gif would update.
I solved the problem by splitting my gif into single images and displaying them in the OnPaint Event of the form
this.Paint += new PaintEventHandler(this.Paint_Background);
The Paint Method looked like this.
private void Paint_Background(object sender, PaintEventArgs e)
{
Graphics background_graphics = e.Graphics;
Graphics graphicsObj;
graphicsObj = this.CreateGraphics();
int image_num = ((int)((DateTime.Now - start_time).TotalMilliseconds) / gif_speed) % num_images;
Image background= Image.FromFile("Filename_"+image_num+".jpg");
background_graphics.DrawImage(background, 0, 0, ClientSize.Width, ClientSize.Height);
background.Dispose();
}
All of my Controls where added directly to the view and not the imagebox anymore, as the imagebox was removed entirely.
Maybe this can help someone else too

How do I show what is behind a windows form?

I need to show what is behind a windows form. I want to minimize the form on startup, take a screenshot of the things behind the form, and set the screen shot as the background image.
I have already tried to following code:
this.WindowState = FormWindowState.Minimized;
var X1 = this.PointToScreen(panel1.Location).X;
var Y1 = this.PointToScreen(panel1.Location).X;
var X2 = this.PointToScreen(panel2.Location).X;
var Y2 = this.PointToScreen(panel2.Location).X;
Bitmap bitmap = new Bitmap(this.Width, this.Height);
Graphics g = Graphics.FromImage(bitmap);
g.CopyFromScreen(X1, Y1, X2, Y2, bitmap.Size);
this.BackgroundImage = bitmap;
this.WindowState = FormWindowState.Normal;
panel 1 is located on the top left corner of the form and panel 2 is located on the bottom left corner of the form
When I run this code however, the background image does not show.
I am using windows forms in c#
If you actually need to set the background image of your form, you may add the following code in your form's Load event handler:
var rect = this.RectangleToScreen(this.ClientRectangle);
Bitmap bitmap = new Bitmap(rect.Width, rect.Height);
//this.WindowState = FormWindowState.Minimized; // If you use the Load event,
// you don't really need this line.
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(rect.Location, Point.Empty, bitmap.Size);
}
this.BackgroundImage = bitmap;
//this.WindowState = FormWindowState.Normal; // Same here.
However, as mentioned in the comments, if you just want to show whatever is behind your form, the Form.Opacity property could be useful. It can help you make the form semi-transparent:
this.Opacity = 0.5;
And you can even make the form semi-transparent (or even fully transparent) except for its controls as shown in this answer.

Resize PictureBox with its related controls

I have a PictureBox where I put some other controls (smaller PictureBoxes, labels..).
PictureBox pictureBox = new PictureBox();
pictureBox.Size = new Size(Width, Height);
pictureBox.Location = new Point(0, 0);
pictureBox.BackColor = Color.Transparent;
pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
// add child controls
PictureBox iconPictureBox = new PictureBox();
iconPictureBox.Location = new Point(icon.x, icon.y);
iconPictureBox.Size = new Size(icon.width, icon.height);
iconPictureBox.BackColor = Color.Transparent;
iconPictureBox.Image = Image.FromFile(resourcesPath);
iconPictureBox.Click += IconPictureBox_Click;
pictureBox.Controls.Add(iconPictureBox);
When I tried to attach the main picture box "pictureBox" to the MainForm window using Controls.Add, after setting the new size and position of the picture box, it is drawn in the correct place with correct size but the contents are not stretched i.e. their positions are not changed.
Is there a method to make the related controls stretched within the main pictureBox?
The scale method of the forms container (PictureBox or Panel) can be used to resize it, all child forms should have the SizeMode to stretch so that they will follow the scaling.

PictureBox not sizing properly

I created a PictureBox and load an image into it, and I wanted the pictures to have a maximum size (let's say 250px). Here is the code I'm using at that moment
PictureBox cellPictureBox = new PictureBox();
cellPictureBox.AutoSize = false;
cellPictureBox.Dock = DockStyle.Fill;
cellPictureBox.SizeMode = PictureBoxSizeMode.Zoom;
cellPictureBox.Image = Base64ToImage(data.ToString().Trim());
cellPictureBox.Width = 250;
cellPictureBox.Height = 250;
When I load the first image, it's quite large. When I load a second image, it's automatically scaled down to be very tiny, and the newly loaded image takesthe large size the first image had. This trend continues as I add more rows to my data.
What can I do to help manage the sizing of my images? Making a custom control I've been told is useful, but I don't see what is happening that I have wrong.
To set maximum and minimum sizes, have a look at the following:
PictureBox cellPictureBox = new PictureBox();
cellPictureBox.AutoSize = false;
cellPictureBox.Dock = DockStyle.Fill;
cellPictureBox.SizeMode = PictureBoxSizeMode.Zoom;
cellPictureBox.Image = Base64ToImage(data.ToString().Trim());
cellPictureBox.MinimumSize = new Size(100, 100); // or whatever size you want.
cellPictureBox.MaximumSize = new Size(250, 250);
If you only want to set a limit on one dimension, for example, the width, but the height is allowed to be anything, then use int.MaxValue:
cellPictureBox.MaximumSize = new Size(250, int.MaxValue);

How to make the underlying control visible instead of form when set the trasparent backcolor

I have added two custom controls in the form as one control placed over the another control. Set the backcolor as trasparent for control1 but it shows the back color as form color instead of underlying control(control2) color. Please share your ideas . Thanks in advance.
Note : For example i have mentioned as picturebox but same problem raises for any controls such as richtextbox or placing the custom controls.
Image link : IssueImage
private void InitializeComponent()
{
#region picturebox
this.BackColor = Color.Aquamarine;
this.WindowState = FormWindowState.Normal;
var selectBtn = new Button();
selectBtn.Size = new Size(100, 30);
selectBtn.Location = new Point(10, 10);
selectBtn.Text = "Click";
//selectBtn.Click += selectBtn_Click;
var picturebox = new PictureBox();
picturebox.Size = new Size(140, 110);
picturebox.Location = new Point(4, 4);
picturebox.SizeMode = PictureBoxSizeMode.StretchImage;
picturebox.Image = new Bitmap(#"..\..\Data\graphic1.png");
var picturebox2 = new PictureBox();
picturebox2.Size = new Size(140, 110);
picturebox2.Location = new Point(4, 4);
picturebox2.SizeMode = PictureBoxSizeMode.StretchImage;
picturebox2.Image = new Bitmap(#"..\..\Data\graphic1.png");
graphiccell = new GraphicCellControl();
graphiccell.Location = new Point(50, 200);
graphiccell.BackColor = Color.Transparent;
graphiccell.Size = new Size(160, 130);
var graphiccell2 = new GraphicCellControl();
graphiccell2.Location = new Point(100, 250);
graphiccell2.BackColor = Color.Red;
graphiccell2.Size = new Size(160, 130);
// graphiccell2.BackColor = Color.Transparent;
graphiccell.Controls.Add(picturebox);
graphiccell2.Controls.Add(picturebox2);
this.Controls.Add(graphiccell);
this.Controls.Add(graphiccell2);
this.Controls.Add(selectBtn);
#endregion
}
public class GraphicCellControl : Control
{
public GraphicCellControl()
{
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}
}
Transparency in Windows Forms follows the rules for Windows windows (ugh). This means that by default, you only get "proper" transparency when you're dealing with the parent-child relationship. Controls behind a transparent control will only be drawn if they are parents of said transparent control.
If this isn't feasible for you for some reason, you can always override the OnPaint or OnPaintBackground methods, and explicitly render whatever control you need to render regardless of the parent-child relationship. Of course, you'll quickly find why this isn't done by default if you can't do a few simplifying assumptions :)
As a quick list of what you need to do when there aren't any simplifications possible:
Find controls that are behind the transparent control - this is especially tricky when there isn't any spatial partitioning (like the mentioned parent-child relationship)
Render the relevant surfaces of the controls from 1. in back to front order on the current control's surface
Optimally, ensure that all the overlapping transparent controls avoid rendering the same controls multiple times
Ensure that all operations that can potentially change the background of the transparent control cause an invalidation (and thus re-render) of the transparent control's background

Categories