Re: Drawing xor line on picture box. HELP! by Peter
Peter
Wed May 07 23:35:31 CDT 2008
On Wed, 07 May 2008 14:36:31 -0700, Macias <maciej.bojczuk@gmail.com> =
wrote:
> I make drawing like this:
>
> private void pb_MouseMove(object sender, MouseEventArgs e)
> {
> Point CurentCoord =3D new Point(e.X, e.Y);
> if (md)
> {
>
> using (Graphics g =3D Graphics.FromImage(img))
> {
> g.CompositingMode =3D CompositingMode.SourceOver;
> g.CompositingQuality =3D
> CompositingQuality.HighSpeed;
> Rectangle rect =3D this.ClientRectangle;
> using (Pen p =3D new Pen(ColorBox.BackColor, 2))
> {
> g.DrawLine(p, ClickCoord, CurentCoord);
> pb.Image =3D img;
> }
> }
> }
>
> but still I've a lot of lines when I moveing mouse. But I want to have=
> only one.
> Please correct my pice of program.
What is the precise reason for using a PictureBox to contain the image? =
=
Are you sure you really need that? Or would it suffice to override =
OnPaint() in your form or a custom control class? I ask, because the us=
e =
of the PictureBox is going to necessarily impose additional overhead on =
=
the redrawing.
The basic issue you've got is that you've apparently started with a give=
n =
Image instance, and to that you want to add a line. However, since you'=
re =
adding a new line every time the mouse moves, you get a lot of lines, =
instead of just the one for the most recent mouse position.
One of the simplest approaches I see based on the code you posted would =
be =
to not draw into the original Image, but rather create a new one:
private void pb_MouseMove(object sender, MouseEventArgs e)
{
Point CurentCoord =3D new Point(e.X, e.Y);
if (md)
{
Image imgT =3D new Bitmap(img);
using (Graphics g =3D Graphics.FromImage(imgT))
{
g.CompositingMode =3D CompositingMode.SourceOver;
g.CompositingQuality =3D
CompositingQuality.HighSpeed;
Rectangle rect =3D this.ClientRectangle;
using (Pen p =3D new Pen(ColorBox.BackColor, 2))
{
g.DrawLine(p, ClickCoord, CurentCoord);
pb.Image =3D imgT;
}
}
}
Optionally (and most likely) in the MouseUp event you'd replace the "img=
" =
reference with the Image currently in the PictureBox.
This is far from an ideal solution though. It can get very expensive to=
=
be creating a new bitmap every time the mouse moves. I haven't use the =
=
PictureBox control much; it's possible you could create one temporary =
image that you repeatedly copy your original image into, and then reassi=
gn =
that to the PictureBox.Image property. That would at least avoid the =
constant instantiation of Bitmaps, but you'd still have a little extra =
overhead every time you copy the original image into the temporary image=
.
It would be much better if you weren't using the PictureBox, but instead=
=
were drawing the Image directly yourself in the appropriate place (form =
or =
custom control). This way you could simply draw both the base Image and=
=
then the line each time the OnPaint() method was called. You'd still =
override OnMouseMove() but the only thing you'd do there is update your =
=
line coordinates and invalidate the area of the form or control containi=
ng =
the old position of the line and the new position of the line.
This way, rather than creating new bitmaps every time the mouse moves, a=
ll =
you have to do is redraw the relevant area based on the current mouse =
position.
Without knowing more about the specific goal you have for your program, =
=
it's hard to offer more detailed advice than the above. Hopefully that =
=
gets you going in the right direction.
Pete