0

I would like a transparent overlapped non-clipped image. I have one PictureBox overlapping another, as shown in this SO thread.

The solution, which makes sense, sets the parent of the top image to the bottom image. The top image is then set to have a transparent background. The technique works perfectly, just setting the parent of the top image to that of the bottom clips the top image to the area of the bottom image.

Top Image Parent Property NOT Set to the Bottom Image

2 separate images with parent set to the main control

Now, here is what happens if the top image parent property gets set to the bottom image.

Clipping effect of top image parent property set to the bottom image

I do not want the top image clipped.

I would volunteer the entire Visual Studio 2019 (VS2019) project, but not sure how to post it.

Here is the code:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace ImageOverlap
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            this.ImgTop.Parent = this.ImgBottom;
            this.ImgTop.BackColor = Color.Transparent;
            //this.ImgTop.BringToFront();
            this.ChangeX.Value = 430;
            this.ChangeY.Value = 15;
        }

        private void ChangeX_ValueChanged(object sender, EventArgs e)
        {
            this.ImgTop.Left = (int)this.ChangeX.Value;
        }

        private void ChangeY_ValueChanged(object sender, EventArgs e)
        {
            this.ImgTop.Top = (int)this.ChangeY.Value;
        }
    }
}

I put 2 NumericUpDown controls to better adjust the position of the finger pointer.

The call to method BringToFront() can be deleted, as does nothing, just above as mentioned in a couple of answers and used for testing.

UPDATE

  • I do NOT want to stretch the bottom image. I want to see the form background.
  • I also realize that the hand pointer is out of bounds of the bottom (parent) image. As such, the hand pointers gets clipped, cut off.

I want to the entirety of the top image to show, just the part of the top image, which overlaps the bottom image to be transparent.

Using what has got to be the world's best app, Paint.Net, here is what I want, also in a nice reusable code format.

Properly non-clipped top image overlapping a bottom image

My thought towards a solution is at the moment to make a programmatic copy of the hand pointer and overlay that using onto the form just clipping the left portion, which overlaps the bottom image. I think this idea might work, will post as answer if it works.

Sarah Weinberger
  • 15,041
  • 25
  • 83
  • 130
  • Location is relative to top-left corner (0,0) of the parent. After changing the parent, you may want to change the location. Set correct location for hand image, then it wont be clipped. – Reza Aghaei Aug 10 '19 at 14:57
  • ImgTop not clipped! it just is out of the bound of it's parent (ImgBottom) change the positon or set SizeMode to Stretch and resize the TopImage. – Mojtaba Tajik Aug 10 '19 at 15:02
  • @MojtabaTajik That is what I said, just not with those exact words. The top image is out of bounds (clipped) of the bottom image. I do not want to stretch the bottom image. – Sarah Weinberger Aug 10 '19 at 15:27
  • @RezaAghaei Location has NOTHING to do with the clipping/out of bounds. I purposely gave the entire code. You can screen grab the 2 images and try for yourself. I also realize that once you change the parent, location changes. I want the hand pointer pointed to the candle. I just do not want the hand cut off, plus I want to see the form background. – Sarah Weinberger Aug 10 '19 at 15:32

2 Answers2

1

This answer can probably be optimized and made more reusable, but it works.

I created a copy of the top control. I then used this updated code, which includes a reusable method.

using System;
using System.Drawing;
using System.Windows.Forms;

namespace ImageOverlap
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            this.ImgTop.Parent = this.ImgBottom;
            this.ImgTop.BackColor = Color.Transparent;
            this.ImgTop.BringToFront();
            this.ChangeX.Value = 430;
            this.ChangeY.Value = 15;
        }

        private void ChangeX_ValueChanged(object sender, EventArgs e)
        {
            this.SetOverlayImageLocation((int)this.ChangeX.Value, this.ImgTop.Top);
        }

        private void ChangeY_ValueChanged(object sender, EventArgs e)
        {
            this.SetOverlayImageLocation(this.ImgTop.Left, (int)this.ChangeY.Value);
        }

        private void SetOverlayImageLocation(int newX, int newY)
        {
            this.ImgTop.Left = newX;
            this.ImgTop.Top = newY;
            Point ptImageAtParent = new Point(this.ImgTop.Left + this.ImgBottom.Left, this.ImgTop.Top + this.ImgBottom.Top);
            this.ImgTopCopy.Location = ptImageAtParent;
            this.ImgTopCopy.SendToBack();
        }
    }
}

I am thinking that .Net probably has a nice method/property to get the point relative to the parent. I did that in a brute force method. I then set the copy to the back. The location of the copy is set relative to the parent. The trick is that the copy has the parent property set to the main control.

Here is the runtime visual that I got, no Paint.Net involved; looks identical, which is the objective.

The nice part is that the NumericUpDown controls work flawlessly moving the combined image, which to the user appears as one image.

Visually properly overlapped non-clipped image, which in reality are 2 separate images.

Sarah Weinberger
  • 15,041
  • 25
  • 83
  • 130
0

You want the entire image render on bottom image, if yes it means your problem is calculation of top image position.

    this.ImgTop.Parent = this.ImgBottom;
    this.ImgTop.BackColor = Color.Transparent;
    this.ImgTop.BringToFront();

    this.ImgTop.Top = 0;
    this.ImgTop.Left = ImgBottom.Width - ImgTop.Width;

I see your replay to Reza, sorry for misunderstood. you set the parent of top image to bottom image. the control can't do any more actions outside of parent area after this. if you want to do that you can dynamically split your image into to separate image controls, one of theme inside the bottom image and another outside and control position of both of theme or implement own control maybe by the help of polygons.

Mojtaba Tajik
  • 1,725
  • 16
  • 34
  • You miss the point. I do NOT want the top image entirely contained inside the bottom image. I realize that I can do what you said. Heck, I am the one that added a `NumericUpDown` control. What I want is to see the entire top image, just have the part that overlaps the bottom image to be transparent. In writing this post, I realize the answer, as stated in my update. I guess there is no easy solution, though can be a new control if I put in a library. – Sarah Weinberger Aug 10 '19 at 15:39
  • Pretty much as I said in my update to the question, just has to be done in a nice reusable way. I need to play with it a bit. I am surprised that in 2019 that Microsoft did not think of this problem. – Sarah Weinberger Aug 10 '19 at 15:46