I have 3 pictureBoxs each one have transparent image, like this:
To make the picture 2 and picture 3 transparent for picture 1 , I wrote this code:
pictureBox2.Parent = pictureBox1;
pictureBox3.Parent = pictureBox1;
Now, my problem: How can I make picture 2 transparent for picture 3?
There's a limit to how well this will work, you are past that limit when you start to nest images. You'll then see that a PictureBox is only transparent against its Parent, parts of the composite image where other PBs contribute pixels won't be visible. You'll see the Parent's background instead.
You'll need to switch to a single PictureBox and write code. Implement its Paint event handler and call e.Graphics.DrawImage() to draw the images. Layering is now no longer a problem, paint is always transparent against its background. Also the way that WPF implements transparency.
Related
I need to put a picturebox above another picture box, the picturebox on top is a png file with a transparent background but when trying to use Picturebox.BringToFront(); the picturebox below is replaced with what is in the background of the form.
I tried to get around this using picturebox.Parent = picturebox2, but I don't want the picturebox to be cut off at the edges of the other picturebox it's on top of.
I'm creating a launcher for a game I'm working on.
I don't want the square edges of the Control, so I decided to try the route in making the control transparent, and having the PictureBox image I created as what you will mainly see as the background of the App itself.
I have the Control Transparency working, however, even though I've set the PictureBox.BackColor to Transparent, it still shows a Black background.
Basically, I just wanted my launcher to look a little "3d" with the logo and the edges coming out a little bit. So the control is technically larger than the picturebox to make room for parts coming out a bit.
Can anyone tell me where I'm going wrong?
Good afternoon!
I have several user controls, each one with a picture box containing an image. A user control represents the backgroud and the other two are elements that must be overlayed.
pictureBox_background.BackColor = Color.Black;
pictureBox_A.BackColor = Color.Transparent;
pictureBox_background.Controls.Add(pictureBox_A);
pictureBox_background.Controls.Add(pictureBox_B);
pictureBox_B.SendToBack();
pictureBox_A.BringToFront();
With this code I get the picturebox A is over picturebox B, but I can not make the background of the element A is the image of the picturebox B. The pictureBox A reaches the background picturebox, and it's background is the black color of the background picturebox.
That is, the transparency of picturebox_A don't shows the picturebox_B, shows the black background, without showing the image of the medium (picturebox_B).
It's a little hard to explain. I hope it was understood.
Thanks in advance!
Specifically: I need to capture as a bitmap a specific region of what a picturebox is actually displaying. The coordinates of the region are specified by the bounds of a control that I have overlayed on top of the picturebox (but that belongs to the picturebox). The control is hidden when I make the "snapshot" of the region.
I tried using normal screen capture methods (CopyFromScreen), but you can't really control the timing there. So it was capturing "interstitial" states, like transitions between photos in my picturebox. Frequently it was only capturing purely black images (the background color of the picture box).
So I tried just converting the image (picturebox.image property) being displayed to a bitmap. The problem there is that the picture box is rarely showing exactly the image. It's displaying some PORTION of the image, scaled and clipped as appropriate to it's sizemode (which is zoom). So the I can't just take my control coordinates and clip them from the image as a whole.
So I tried to estimate what portion of the image was being displayed, and correcting my rectangle based on that. Turns out that I was basically re-creating the "zoom" code of the picturebox to do this (using aspect ratio of the picturebox, the aspect ratio of the image, guessing at what level of scaling is currently happening to the image if it's larger or smaller than the picturebox, etc). It was not pretty.
So: now I need a method of just capturing only the bitmap currently being displayed in the client area of the picturebox, including the photo and any black "letterboxing" currently being displayed around it. Anybody got one?
Remember that I can't rely on using CopyFromScreen. It's not reliable enough for my purposes. I think I need a method of getting picturebox to TELL me the bits it is displaying.
This will copy and save the currently shown content of the PictureBox including a BackgroundImage (if there is one and if it shines through) and also all Controls that belong to the PictureBox, like Labels etc.. Also included are elements drawn in the Paint event. Things drawn outside the Paint event are non-persistent and will not be included.
using (Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width,
pictureBox1.ClientSize.Height))
{
pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle);
bmp.Save(yourfilename, ImageFormat.Png);
}
Note: On my test Form the PicureBox is sitting inside an AutoScroll Panel pan_PBscroll. The PictureBox is displaying pixels 1:1 and is therefore, with a photograph loaded, much bigger than the Panel, the Form or even the Screen. So to clip to the actually visible parts I could not use the pictureBox1.ClientSize and pictureBox1.ClientRectangle but used the dimensions of that Panel. This may well apply to you, too.
I'm not sure about your timing issues. But since you mentioned CopyFromScreen here are a few differences:
CopyFromScreen makes a 1:1 copy of each screen pixel
This includes non-persistent drawings and excludes anything covered or hidden
Control.DrawToBitmap makes the Control draw itself onto a Bitmap, just as it draws itself during Paint
This excludes anything that doesn't belong to the Control but includes all members of its Controls collection
This also excludes non-persistent drawings but includes the full Size of the Control, whether it fits on the Form or Screen or not and whether it is hidden or covered or not.
For Controls with active Scrollbars only the visible parts are copied. To copy all you need to resize it temporarily. Then you can get a complete image of a listbox even if it has a thousand items..
Since you're using a PictureBox I would say to take a look PictureBox.Image where you can get the Bitmap object.
Hope it helps.
Imagine there's a picturebox which loads a monochrome image. And there is a need to make few color scribbles on it. I have no background with graphics. Would it be just a pen drawing pixels or something more complex I don't know.
Target language is C#. Technology: WinForms.
I think the easiest way to achieve what you want would be to create a very lightweight retained mode drawing system. Keep track of all the positions where the user has scribbeled and draw dots/circles/lines/rubberducks/whatever at these positions in the PictureBox's Paint event. On mousedown+move events, call the PictureBox' Invalidate() function. The original picture must either be painted underneath or in the class' OnPaintBackground (which IMO is more elegant).
This tutorial should get you started:
https://web.archive.org/web/20121006140255/http://www.bobpowell.net/backtrack.htm