none
How can i move png picture over png picture in form ?

    Question

  • hi all .

    i want a help with this i want to move a png photo over another png photo ...

    for example

    i want to move pic A over pic B and  i replaces the backcolor of the tow pic to Transparent

    but when pic A over B the its look like this

    i don't want to see it like that i want to see images...

    how can help with it pleas ?

    • Changed type Rudedog2MVP Tuesday, April 10, 2012 12:21 AM : post is a question :
    • Moved by Rudedog2MVP Saturday, April 14, 2012 4:23 PM : move to more appropriate forum : (From:Visual C# General)
    Monday, April 09, 2012 11:32 PM

Answers

  • Hi,

    if the image on top has a transparent background, you simply could draw it over the other image:

        public partial class Form1 : Form
        {
            private Bitmap _testBmpA;
            private Bitmap _testBmpB;
            private int _x = 0;
    
            private Timer t = new Timer();
    
            public Form1()
            {
                InitializeComponent();
    
                //avoid flickering
                this.DoubleBuffered = true;
    
                //move initially out of sight
                _x = this.ClientSize.Width;
    
                //add eventhandlers
                this.Load += new System.EventHandler(this.Form1_Load);
                this.Paint += new PaintEventHandler(Form1_Paint);
                t.Tick += new EventHandler(t_Tick);
                this.FormClosed += new FormClosedEventHandler(Form1_FormClosed);
    
                t.Interval = 10;
            }
    
            void Form1_FormClosed(object sender, FormClosedEventArgs e)
            {
                if (_testBmpA != null)
                    _testBmpA.Dispose();
    
                if (_testBmpB != null)
                    _testBmpB.Dispose();
    
                if (t != null)
                    t.Dispose();
            }
    
            void t_Tick(object sender, EventArgs e)
            {
                t.Stop();
    
                _x--;
                //repaint the window
                this.Invalidate();
    
                if (_x > 0)
                    t.Start();
            }
    
            void Form1_Paint(object sender, PaintEventArgs e)
            {
                //draw out the pictures
                if (_testBmpA != null)
                    e.Graphics.DrawImage(_testBmpA, 0, 0);
                if (_testBmpB != null)
                    e.Graphics.DrawImage(_testBmpB, _x, 0);
            }
    
    
            private void Form1_Load(object sender, EventArgs e)
            {
                //create two bitmaps with transparent backgrounds on the fly to test with
                _testBmpA = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
    
                using (Graphics g = Graphics.FromImage(_testBmpA))
                {
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                    g.FillEllipse(Brushes.Green, new Rectangle(0, 0, _testBmpA.Width, _testBmpA.Height));
                }
    
                _testBmpB = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
    
                using (Graphics g = Graphics.FromImage(_testBmpB))
                {
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                    g.FillEllipse(Brushes.Red, new Rectangle(0, 0, _testBmpB.Width / 2, _testBmpB.Height / 2));
                }
    
                //start the animation
                t.Start();
            }
        }

    Regards,

      Thorsten


    Tuesday, April 10, 2012 2:31 AM
  • Ok, so lets examine what we need.

    We want to draw an Image to a Control and also want to overlay one ore more images on top of that other image. So we first create an appropriate control that holds the information (- the background image - and all overlay images) -> I call it MyDoubleBufferedPanel:

        //this is the control to draw a background image and
        //various overlay images on top of it
        public class MyDoubleBufferedPanel : Panel
        {
            //the basic Image
            public Bitmap BackGround { get; set; }
    
            //a list to hold all overlay Images
            //note that it would be better to
            //expose some methods to add/remove bitmaps to that list
            //- like we do whith the "Add" method - 
            //instead of exposing the whole list
            private List<BitmapShape> _overlayImages = null;
            public List<BitmapShape> OverlayImages 
            {
                get { return _overlayImages; }
                set { _overlayImages = value; } 
            }
    
            public MyDoubleBufferedPanel()
            {
                //avoid flickering
                this.DoubleBuffered = true;
            }
    
            //paint
            protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);
    
                //background
                if (BackGround != null)
                    e.Graphics.DrawImage(BackGround, 0, 0);
    
                //overlays
                if (_overlayImages != null)
                {
                    //let each overlay image paint itself
                    for (int i = 0; i < _overlayImages.Count; i++)
                        _overlayImages[i].Render(e.Graphics);
                }
            }
    
            public void Add(BitmapShape b)
            {
                if (this._overlayImages == null)
                    _overlayImages = new List<BitmapShape>();
    
                _overlayImages.Add(b);
            }
    
            //cleanup 
            protected override void Dispose(bool disposing)
            {
                if (BackGround != null)
                    BackGround.Dispose();
    
                if (_overlayImages != null)
                {
                    for (int i = _overlayImages.Count - 1; i >= 0; i--)
                        _overlayImages[i].Dispose();
                }
                base.Dispose(disposing);
            }
        }

    Now we need the class that defines one overlay image, I call it BitmapShape, combining a Bitmap with a Location:

        //this is the Type that connects a Bitmap with a Location
        public class BitmapShape:IDisposable
        {
            public Bitmap Bmp { get; set; }
            public PointF Location { get; set; }
    
            //let the object draw itself
            public void Render(Graphics g)
            {
                g.DrawImage(Bmp, Location);
            }
    
            //cleanup
            public void Dispose()
            {
                if (Bmp != null)
                    Bmp.Dispose();
            }
        }

    And, basically we are done.

    If we now add that code to a codefile and build the project, we could use that MyDoubleBufferedContols from the designer, add the images set their locations.

    I uploaded a small project to:

    https://skydrive.live.com/redir.aspx?cid=d5e5bd21dbf5e4e9&resid=D5E5BD21DBF5E4E9!2269&parid=D5E5BD21DBF5E4E9!1901&authkey=!

    (note: change the paths to the images on disc)

    Regards,

      Thorsten


    Saturday, April 14, 2012 10:14 AM
  • The easiest thing to do would be to use a GraphicsPath object to define the Region property, or shape, of the PictureBox.

    Control.Region Property (System.Windows.Forms)   

    GraphicsPath Class (System.Drawing.Drawing2D)  

    You can define a sequence of points that define line segments that define the outline of the image.  Tediouis for A.  Urgh.  There are far more sophisticated ways of drawing the images, though.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Tuesday, April 10, 2012 12:20 AM
  • It is in fact very easy if you use the bitmapimage while creating first transparants using Bitmap maketransparant

    http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.maketransparent.aspx

    Then you can by using a memory stream stream this to a bitmapimage.

     http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapimage.aspx

    By using the imagedrawing you can then create your picture. (the link below contains a complete sample with pictures like yours)

    http://msdn.microsoft.com/en-us/library/system.windows.media.imagedrawing.aspx

    Streaming it back to bitmap gives you then the obtained result. 

    I've done this (more times), but not in a complete simple piece of code but all separated methods so not easy to show as sample.  
    The streaming part between bitmaps and bitmapimages is easily to find hundreds times on Internet.


    Success
    Cor


    Wednesday, April 11, 2012 7:10 AM

All replies

  • The easiest thing to do would be to use a GraphicsPath object to define the Region property, or shape, of the PictureBox.

    Control.Region Property (System.Windows.Forms)   

    GraphicsPath Class (System.Drawing.Drawing2D)  

    You can define a sequence of points that define line segments that define the outline of the image.  Tediouis for A.  Urgh.  There are far more sophisticated ways of drawing the images, though.

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Tuesday, April 10, 2012 12:20 AM
  • Hi,

    if the image on top has a transparent background, you simply could draw it over the other image:

        public partial class Form1 : Form
        {
            private Bitmap _testBmpA;
            private Bitmap _testBmpB;
            private int _x = 0;
    
            private Timer t = new Timer();
    
            public Form1()
            {
                InitializeComponent();
    
                //avoid flickering
                this.DoubleBuffered = true;
    
                //move initially out of sight
                _x = this.ClientSize.Width;
    
                //add eventhandlers
                this.Load += new System.EventHandler(this.Form1_Load);
                this.Paint += new PaintEventHandler(Form1_Paint);
                t.Tick += new EventHandler(t_Tick);
                this.FormClosed += new FormClosedEventHandler(Form1_FormClosed);
    
                t.Interval = 10;
            }
    
            void Form1_FormClosed(object sender, FormClosedEventArgs e)
            {
                if (_testBmpA != null)
                    _testBmpA.Dispose();
    
                if (_testBmpB != null)
                    _testBmpB.Dispose();
    
                if (t != null)
                    t.Dispose();
            }
    
            void t_Tick(object sender, EventArgs e)
            {
                t.Stop();
    
                _x--;
                //repaint the window
                this.Invalidate();
    
                if (_x > 0)
                    t.Start();
            }
    
            void Form1_Paint(object sender, PaintEventArgs e)
            {
                //draw out the pictures
                if (_testBmpA != null)
                    e.Graphics.DrawImage(_testBmpA, 0, 0);
                if (_testBmpB != null)
                    e.Graphics.DrawImage(_testBmpB, _x, 0);
            }
    
    
            private void Form1_Load(object sender, EventArgs e)
            {
                //create two bitmaps with transparent backgrounds on the fly to test with
                _testBmpA = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
    
                using (Graphics g = Graphics.FromImage(_testBmpA))
                {
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                    g.FillEllipse(Brushes.Green, new Rectangle(0, 0, _testBmpA.Width, _testBmpA.Height));
                }
    
                _testBmpB = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
    
                using (Graphics g = Graphics.FromImage(_testBmpB))
                {
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
                    g.FillEllipse(Brushes.Red, new Rectangle(0, 0, _testBmpB.Width / 2, _testBmpB.Height / 2));
                }
    
                //start the animation
                t.Start();
            }
        }

    Regards,

      Thorsten


    Tuesday, April 10, 2012 2:31 AM
  • thanks for answer ..

    i don't want to draw a fillEllipse or any thing ... i have tow png photo

    you can tray it

    1... put  2 png photo in picturebox1 and picuterbox2 ..

    2....and give the backcolor for picuterbox1 and picuterbox2 to Transparent then

    3.... move picuterbox1 over picuterbox2 with Timer or button

           pictureBox2.Left = pictureBox2.Left - 10;

    i need a help with it pleas ...

    Wednesday, April 11, 2012 4:48 AM
  • Hi,

    what is shown in the code example is a general way to achieve it. The Bitmaps created on the fly are just example bitmaps and thus can be replaced by any picture from file (that gdi+ supports). I just wanted to show an easy way without the need of tweaking params of the containing control to get a transparent background...

    Regards,

      Thorsten

    Wednesday, April 11, 2012 5:24 AM
  • ... see:

    http://www.bobpowell.net/transcontrols.htm

    Regards,

      Thorsten

    Wednesday, April 11, 2012 5:35 AM
  • It is in fact very easy if you use the bitmapimage while creating first transparants using Bitmap maketransparant

    http://msdn.microsoft.com/en-us/library/system.drawing.bitmap.maketransparent.aspx

    Then you can by using a memory stream stream this to a bitmapimage.

     http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.bitmapimage.aspx

    By using the imagedrawing you can then create your picture. (the link below contains a complete sample with pictures like yours)

    http://msdn.microsoft.com/en-us/library/system.windows.media.imagedrawing.aspx

    Streaming it back to bitmap gives you then the obtained result. 

    I've done this (more times), but not in a complete simple piece of code but all separated methods so not easy to show as sample.  
    The streaming part between bitmaps and bitmapimages is easily to find hundreds times on Internet.


    Success
    Cor


    Wednesday, April 11, 2012 7:10 AM
  • dear Thorsten

    i can't understand your code I am a newer in programming and in  Visual c#...

    can you tell me where can i repeals my png photo in the the code an how can i use it plz ..

    Saturday, April 14, 2012 5:51 AM
  • Ok, so lets examine what we need.

    We want to draw an Image to a Control and also want to overlay one ore more images on top of that other image. So we first create an appropriate control that holds the information (- the background image - and all overlay images) -> I call it MyDoubleBufferedPanel:

        //this is the control to draw a background image and
        //various overlay images on top of it
        public class MyDoubleBufferedPanel : Panel
        {
            //the basic Image
            public Bitmap BackGround { get; set; }
    
            //a list to hold all overlay Images
            //note that it would be better to
            //expose some methods to add/remove bitmaps to that list
            //- like we do whith the "Add" method - 
            //instead of exposing the whole list
            private List<BitmapShape> _overlayImages = null;
            public List<BitmapShape> OverlayImages 
            {
                get { return _overlayImages; }
                set { _overlayImages = value; } 
            }
    
            public MyDoubleBufferedPanel()
            {
                //avoid flickering
                this.DoubleBuffered = true;
            }
    
            //paint
            protected override void OnPaint(PaintEventArgs e)
            {
                base.OnPaint(e);
    
                //background
                if (BackGround != null)
                    e.Graphics.DrawImage(BackGround, 0, 0);
    
                //overlays
                if (_overlayImages != null)
                {
                    //let each overlay image paint itself
                    for (int i = 0; i < _overlayImages.Count; i++)
                        _overlayImages[i].Render(e.Graphics);
                }
            }
    
            public void Add(BitmapShape b)
            {
                if (this._overlayImages == null)
                    _overlayImages = new List<BitmapShape>();
    
                _overlayImages.Add(b);
            }
    
            //cleanup 
            protected override void Dispose(bool disposing)
            {
                if (BackGround != null)
                    BackGround.Dispose();
    
                if (_overlayImages != null)
                {
                    for (int i = _overlayImages.Count - 1; i >= 0; i--)
                        _overlayImages[i].Dispose();
                }
                base.Dispose(disposing);
            }
        }

    Now we need the class that defines one overlay image, I call it BitmapShape, combining a Bitmap with a Location:

        //this is the Type that connects a Bitmap with a Location
        public class BitmapShape:IDisposable
        {
            public Bitmap Bmp { get; set; }
            public PointF Location { get; set; }
    
            //let the object draw itself
            public void Render(Graphics g)
            {
                g.DrawImage(Bmp, Location);
            }
    
            //cleanup
            public void Dispose()
            {
                if (Bmp != null)
                    Bmp.Dispose();
            }
        }

    And, basically we are done.

    If we now add that code to a codefile and build the project, we could use that MyDoubleBufferedContols from the designer, add the images set their locations.

    I uploaded a small project to:

    https://skydrive.live.com/redir.aspx?cid=d5e5bd21dbf5e4e9&resid=D5E5BD21DBF5E4E9!2269&parid=D5E5BD21DBF5E4E9!1901&authkey=!

    (note: change the paths to the images on disc)

    Regards,

      Thorsten


    Saturday, April 14, 2012 10:14 AM
  • thank you very mach  dear  Thorsten  Gudera 

    and i have another question .. i m so sorry about my of questions , but i m hope you helped me again , and know you are the best and a big man hoe can help me ..

    if i have add a png photo to project how can i call array photo for example

    i add 10 photo where the name of photo foto_1 to foto 10

    and i want to call the foto from Resources         for (int i = 1; i < 10; i++)
                    pictureBox1.Image =( Properties.Resources.foto_ +"i");

    but its not work like this .

    i use image list but photo size maximum (256 ,256) ,i have the size (600,400)

           count= (count+1)%8;
                pictureBox1.Image=imageList1.Images[count];

    in this it work but photo resolution not good

    how can use array photo from resources plz .

    and thank you again dear .

    and i hoe you can you helped in this too .....

    Saturday, April 14, 2012 11:02 PM
  • thank you very mach  dear  Thorsten  Gudera 

    and i have another question .. i m so sorry about my of questions , but i m hope you helped me again , and know you are the best and a big man hoe can help me ..

    if i have add a png photo to project how can i call array photo for example

    i add 10 photo where the name of photo foto_1 to foto 10

    and i want to call the foto from Resources         for (int i = 1; i < 10; i++)
                    pictureBox1.Image =( Properties.Resources.foto_ +"i");

    but its not work like this .

    i use image list but photo size maximum (256 ,256) ,i have the size (600,400)

           count= (count+1)%8;
                pictureBox1.Image=imageList1.Images[count];

    in this it work but photo resolution not good

    how can use array photo from resources plz .

    and thank you again dear .

    and i hoe you can you helped in this too .....

    If you have a new issue, then you should close this thread by marking the best reply as Answer and start a new thread.  We strive to have on issue per thread, which makes it easier for people to search for solutions in existing threads.

    thanks, ahead of time.  

    Rudy   =8^D


    Mark the best replies as answers. "Fooling computers since 1971."

    http://thesharpercoder.blogspot.com/

    Saturday, April 14, 2012 11:05 PM
  • Hi,

    yes, do as Rudedog sais and start a new thread with your question...

    Regards,

      Thorsten

    Saturday, April 14, 2012 11:50 PM