BLOG.CSHARPHELPER.COM: Let the user drag an image with transparent pixels over a background image in C#
Let the user drag an image with transparent pixels over a background image in C#
This program contains a PictureBox with Image property set to the background image. The user can press the mouse down on any of the image's non-transparent pixels to drag the image.
The program stores the image's location in a Rectangle named SmileyLocation. When it starts, the program loads the image from a resource, uses its MakeTransparent method to make white pixels in the image transparent, and initializes the location.
// The smiley image. private Bitmap Smiley;
// The smiley image's location. private Rectangle SmileyLocation;
private void Form1_Load(object sender, EventArgs e) { // Make the white pixels in the smiley transparent. Smiley = new Bitmap(Properties.Resources.smile); Smiley.MakeTransparent(Color.White);
// Set the smiley's initial location. SmileyLocation = new Rectangle(10, 10, Smiley.Width, Smiley.Height); }
The PictureBox's Paint event handler simply draws the picture above the background.
// Draw the picture over the background. private void picBackground_Paint(object sender, PaintEventArgs e) { e.Graphics.DrawImage(Smiley, SmileyLocation); }
When the user presses mouse down over the PictureBox, the following MouseDown event executes.
// True when we are dragging. private bool Dragging = false;
// The offset from the mouse's down position // and the picture's upper left corner. private int OffsetX, OffsetY;
// Start dragging the picture. private void picBackground_MouseDown(object sender, MouseEventArgs e) { // See if we're over the picture. if (PointIsOverPicture(e.X, e.Y)) { // Start dragging. Dragging = true;
// Record the offset from the mouse to the picture's origin. OffsetX = SmileyLocation.X - e.X; OffsetY = SmileyLocation.Y - e.Y; } }
This code uses the PointIsOverPicture method described shortly to see if the mouse is over one of the image's non-transparent pixels. If it is, the code sets Dragging to true to indicate that a drag is started and saves the offset from the mouse's location to the image's location.
When the mouse moves, the following event handler executes.
// Continue dragging the picture. private void picBackground_MouseMove(object sender, MouseEventArgs e) { // See if we're dragging. if (Dragging) { // We're dragging the image. Move it. SmileyLocation.X = e.X + OffsetX; SmileyLocation.Y = e.Y + OffsetY;
// Redraw. picBackground.Invalidate(); } else { // We're not dragging the image. See if we're over it. Cursor new_cursor = Cursors.Default; if (PointIsOverPicture(e.X, e.Y)) { new_cursor = Cursors.Hand; } if (picBackground.Cursor != new_cursor) picBackground.Cursor = new_cursor; } }
If a drag is in progress, the program uses the initial offset from the mouse to the image to update the image's current position. It then invalidates the PictureBox so its Paint event handler redraws it.
If no drag is in progress, the program uses PointIsOverPicture to see if the mouse is over a non-transparent pixel in the image. It then sets the PictureBox's cursor appropriately.
The PictureBox's MouseUp event handler simply stops the drag.
The last piece to the program is the PointIsOverPicture method.
// Return true if the point is over the picture's current location. private bool PointIsOverPicture(int x, int y) { // See if it's over the picture's bounding rectangle. if ((x < SmileyLocation.Left) || (y < SmileyLocation.Top) || (x >= SmileyLocation.Right) || (y >= SmileyLocation.Bottom)) return false;
// See if the point is above a non-transparent pixel. int i = x - SmileyLocation.X; int j = y - SmileyLocation.Y; return (Smiley.GetPixel(i, j).A > 0); }
First this method determines whether the point lies within the image's bounding box and returns false if it does not.
If the point does lie within the image's bounding box, the program figures out which of the image's pixels is under the mouse and returns true if that pixel is non-transparent.
Comments