Is it possible to remove existing graphics from an image?
-
Hi I am trying to draw a rectangle over an existing image by using the following code (pb is the PictureBox and has an image)
Graphics oGraphics = Graphics.FromImage(pb.Image); oGraphics.DrawRectangle(new Pen(Color.Red, 2), new Rectangle(5, 5, 300, 300)); pb.Refresh();
The problem comes when I want to draw another rectangle (at a different location) and I can't remove/clear the existing rectangle before drawing the new one. Is there any way I can remove the existing drawn rectangle? I don't want to use the pb.CreateGraphics() b/c the drawing is not consistent when this method is used. I am using the FromImage() method b/c later I want to resize (zoom) or rotate the image with drawn rectangle and It won't require any further coding for rotating and resizing the rectangle. I tried reload the Image again, but large images take to much time to load, so I want to avoid the Image reloading. Please help! -
Hi I am trying to draw a rectangle over an existing image by using the following code (pb is the PictureBox and has an image)
Graphics oGraphics = Graphics.FromImage(pb.Image); oGraphics.DrawRectangle(new Pen(Color.Red, 2), new Rectangle(5, 5, 300, 300)); pb.Refresh();
The problem comes when I want to draw another rectangle (at a different location) and I can't remove/clear the existing rectangle before drawing the new one. Is there any way I can remove the existing drawn rectangle? I don't want to use the pb.CreateGraphics() b/c the drawing is not consistent when this method is used. I am using the FromImage() method b/c later I want to resize (zoom) or rotate the image with drawn rectangle and It won't require any further coding for rotating and resizing the rectangle. I tried reload the Image again, but large images take to much time to load, so I want to avoid the Image reloading. Please help!Hi! I'm afraid you can't do this. You'll have to store the base image somewhere, duplicate it and then perform all the painting you want to be seen one after the other. That way you don't modify the original image and you can draw the original version as often as you like. In order to remove the rectangle you've drawn previously you'd have to remember all the pixel values for each pixel your rectangle is drawn over and then restore them one by one. I strongly doubt that this is working efficiently, especially when you have more forms than just a rectangle. Regards, mav
-
Hi I am trying to draw a rectangle over an existing image by using the following code (pb is the PictureBox and has an image)
Graphics oGraphics = Graphics.FromImage(pb.Image); oGraphics.DrawRectangle(new Pen(Color.Red, 2), new Rectangle(5, 5, 300, 300)); pb.Refresh();
The problem comes when I want to draw another rectangle (at a different location) and I can't remove/clear the existing rectangle before drawing the new one. Is there any way I can remove the existing drawn rectangle? I don't want to use the pb.CreateGraphics() b/c the drawing is not consistent when this method is used. I am using the FromImage() method b/c later I want to resize (zoom) or rotate the image with drawn rectangle and It won't require any further coding for rotating and resizing the rectangle. I tried reload the Image again, but large images take to much time to load, so I want to avoid the Image reloading. Please help!If you modifiy an image like you do it in your example there is no way going back to a previous state. One solution would be to clone the whole image before altering it and going back to the original one when needed. Another possibility would be to catch the Paint event of the PictureBox and paint the 'current' rectangle in the handler. It would probably even be a good idea to dump the PictureBox and draw image and rectangle yourself.
-
Hi I am trying to draw a rectangle over an existing image by using the following code (pb is the PictureBox and has an image)
Graphics oGraphics = Graphics.FromImage(pb.Image); oGraphics.DrawRectangle(new Pen(Color.Red, 2), new Rectangle(5, 5, 300, 300)); pb.Refresh();
The problem comes when I want to draw another rectangle (at a different location) and I can't remove/clear the existing rectangle before drawing the new one. Is there any way I can remove the existing drawn rectangle? I don't want to use the pb.CreateGraphics() b/c the drawing is not consistent when this method is used. I am using the FromImage() method b/c later I want to resize (zoom) or rotate the image with drawn rectangle and It won't require any further coding for rotating and resizing the rectangle. I tried reload the Image again, but large images take to much time to load, so I want to avoid the Image reloading. Please help!You have at least 2 solutions: 1. Create a class that extends PictureBox (or Control if you get adventurous) and override OnPaint(). 2. Keep a copy of the image in memory. I think the 1st option is the better choice because it opens the possibility for code-reuse and uses less memory. Example:
public class PictureSelectionBox : PictureBox
{
private Rectangle selectionRect;
private Pen selectionPen;public Rectangle CurrentSelection
{
get { return this.selectionRect; }
set
{
this.selectionRect = value;
this.Refresh();
}
}public Pen SelectionPen
{
get { return this.selectionPen; }
set
{
this.selectionPen = value;
this.Refresh();
}
}protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);if (this.selectionPen != null && this.selectionRect.Width != 0 && this.selectionRect.Height != 0) { e.Graphics.DrawRectangle(this.selectionPen, this.selectionRect); }
}
public void CommitSelection()
{
Graphics g = Graphics.FromImage(base.Image);
g.DrawRectangle(this.selectionPen, this.selectionRect);
g.Dispose();this.CurrentSelection = new Rectangle(0, 0, 0, 0); this.Refresh();
}
}You could even override the OnMouseDown, OnMouseMove, and OnMouseUp events in the derived class to allow the user to make his/her selection. You better watch out with the use of Refresh() doing this though because you'll get some ugly flickering. I'd either [DllImport] InvalidateRect() or something like:
Graphics g = this.CreateGraphics();
OnPaint(new PaintEventArgs(g, this.ClientRectangle));
g.Dispose();Enjoy, David
-
You have at least 2 solutions: 1. Create a class that extends PictureBox (or Control if you get adventurous) and override OnPaint(). 2. Keep a copy of the image in memory. I think the 1st option is the better choice because it opens the possibility for code-reuse and uses less memory. Example:
public class PictureSelectionBox : PictureBox
{
private Rectangle selectionRect;
private Pen selectionPen;public Rectangle CurrentSelection
{
get { return this.selectionRect; }
set
{
this.selectionRect = value;
this.Refresh();
}
}public Pen SelectionPen
{
get { return this.selectionPen; }
set
{
this.selectionPen = value;
this.Refresh();
}
}protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);if (this.selectionPen != null && this.selectionRect.Width != 0 && this.selectionRect.Height != 0) { e.Graphics.DrawRectangle(this.selectionPen, this.selectionRect); }
}
public void CommitSelection()
{
Graphics g = Graphics.FromImage(base.Image);
g.DrawRectangle(this.selectionPen, this.selectionRect);
g.Dispose();this.CurrentSelection = new Rectangle(0, 0, 0, 0); this.Refresh();
}
}You could even override the OnMouseDown, OnMouseMove, and OnMouseUp events in the derived class to allow the user to make his/her selection. You better watch out with the use of Refresh() doing this though because you'll get some ugly flickering. I'd either [DllImport] InvalidateRect() or something like:
Graphics g = this.CreateGraphics();
OnPaint(new PaintEventArgs(g, this.ClientRectangle));
g.Dispose();Enjoy, David
Thank You David, Let me check it out!