在PictureBox C#上刮擦图像 [英] Scratch Image on PictureBox C#

查看:106
本文介绍了在PictureBox C#上刮擦图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对此进行了编码,以在图片框上刮擦图像.

bool draw = false;

int pX = -1;
int pY = -1;

Bitmap drawing;

public Form1()
{
    drawing = new Bitmap(transformedImage.Width, transformedImage.Height, transformedImage.CreateGraphics());
    Graphics.FromImage(drawing).Clear(Color.Transparent);
}

private void transformedImage_MouseMove(object sender, MouseEventArgs e)
    {
        if (draw)
        {
            int penWidth = Convert.ToInt32(penWidthValue.Value);
            if(blackCheck.Checked == true) ///black pen
            {
                Graphics panel = Graphics.FromImage(drawing);

                Pen pen = new Pen(Color.Black, penWidth);

                pen.EndCap = LineCap.Round;
                pen.StartCap = LineCap.Round;

                panel.DrawLine(pen, pX, pY, e.X, e.Y);

                transformedImage.CreateGraphics().DrawImageUnscaled(drawing, new Point(0, 0));                    
            }
            else if(redCheck.Checked == true) /// red pen
            {
                Graphics panel = Graphics.FromImage(drawing);

                Pen pen = new Pen(Color.Red, penWidth);

                pen.EndCap = LineCap.Round;
                pen.StartCap = LineCap.Round;

                panel.DrawLine(pen, pX, pY, e.X, e.Y);

                transformedImage.CreateGraphics().DrawImageUnscaled(drawing, new Point(0, 0));
            }
            else if(yellowCheck.Checked == true) /// yellow
            {
                Graphics panel = Graphics.FromImage(drawing);

                Pen pen = new Pen(Color.Yellow, penWidth);

                pen.EndCap = LineCap.Round;
                pen.StartCap = LineCap.Round;

                panel.DrawLine(pen, pX, pY, e.X, e.Y);

                transformedImage.CreateGraphics().DrawImageUnscaled(drawing, new Point(0, 0));
            }
            else /// green
            {
                Graphics panel = Graphics.FromImage(drawing);

                Pen pen = new Pen(Color.Green, penWidth);

                pen.EndCap = LineCap.Round;
                pen.StartCap = LineCap.Round;

                panel.DrawLine(pen, pX, pY, e.X, e.Y);

                transformedImage.CreateGraphics().DrawImageUnscaled(drawing, new Point(0, 0));
            }

        }

        pX = e.X;
        pY = e.Y;
    }

    private void transformedImage_MouseDown(object sender, MouseEventArgs e)
    {
        if (scratchCheck.Checked == true)
        {
            draw = true;
            pX = e.X;
            pY = e.Y;
        }
    }

    private void transformedImage_MouseUp(object sender, MouseEventArgs e)
    {
        draw = false;
    }

    private void transformedImage_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.DrawImageUnscaled(drawing, new Point(0, 0));  
    }

但是当我使用此方法保存图像时:

SaveFileDialog sfd = new SaveFileDialog();
                sfd.Title = "Select Save Location";
                sfd.InitialDirectory = @"Save_Path";
                sfd.AddExtension = true;
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    switch (Path.GetExtension(sfd.FileName).ToUpper())
                    {
                        case ".BMP":
                            bmp.Save(sfd.FileName, ImageFormat.Bmp);
                            break;
                        case ".gif":
                            bmp.Save(sfd.FileName, ImageFormat.Gif);
                            break;
                        case ".JPG":
                            bmp.Save(sfd.FileName, ImageFormat.Jpeg);
                            break;
                        case ".JPEG":
                            bmp.Save(sfd.FileName,ImageFormat.Jpeg);
                            break;
                        case ".PNG":
                            bmp.Save(sfd.FileName, ImageFormat.Png);
                            break;
                        case ".png":
                            bmp.Save(sfd.FileName, ImageFormat.Png);
                            break;
                        default:
                            break;
                    }
                }

未刮开图片盒上刮擦的图像.

在保存之前,这是图片盒上的划痕图像:

但是当我使用上面的代码保存时,划痕丢失了:

如何保存图片和划痕?,非常感谢.

解决方案

两个常见错误:

  1. 使用CreateGraphics不会创建永久图形.因此:Alwas在PictureBoxPaint事件中绘制了所有内容! MouseMove应该仅收集 List<Point>List<List<Point>>中的点. 所有图形必须使用其e.Graphics对象在Paint事件中发生!

  2. 仅当使用DrawToBitmap创建新的位图时,表面上的图形才会保存,该位图将合并最多 3层:BackgroundImageImage以及所有永久性图形.

请参见此处以绘画为例,并在此处有关使用DrawToBitmap

的示例

作为推荐的绘制Image方式的替代方法,您也可以直接将其绘制.这是MouseMove中实际执行的操作,但是稍后您将忽略图像并以非持久方式绘制它.

最后:Save例程正在保存您没有显示给我们的bmp,因此我们只能得出结论,它是您加载的原始Image.也许drawing.Save(..)会有所帮助. >

但是代码有很多问题,您真的应该从令人困惑的名称开始完全重写! (提示:不要用不同类型的名称来命名对象,例如Graphics panel !!!!)显然,类型为PenColor的变量也将有助于避免重复...

I coded this to scratch image on picturebox.

bool draw = false;

int pX = -1;
int pY = -1;

Bitmap drawing;

public Form1()
{
    drawing = new Bitmap(transformedImage.Width, transformedImage.Height, transformedImage.CreateGraphics());
    Graphics.FromImage(drawing).Clear(Color.Transparent);
}

private void transformedImage_MouseMove(object sender, MouseEventArgs e)
    {
        if (draw)
        {
            int penWidth = Convert.ToInt32(penWidthValue.Value);
            if(blackCheck.Checked == true) ///black pen
            {
                Graphics panel = Graphics.FromImage(drawing);

                Pen pen = new Pen(Color.Black, penWidth);

                pen.EndCap = LineCap.Round;
                pen.StartCap = LineCap.Round;

                panel.DrawLine(pen, pX, pY, e.X, e.Y);

                transformedImage.CreateGraphics().DrawImageUnscaled(drawing, new Point(0, 0));                    
            }
            else if(redCheck.Checked == true) /// red pen
            {
                Graphics panel = Graphics.FromImage(drawing);

                Pen pen = new Pen(Color.Red, penWidth);

                pen.EndCap = LineCap.Round;
                pen.StartCap = LineCap.Round;

                panel.DrawLine(pen, pX, pY, e.X, e.Y);

                transformedImage.CreateGraphics().DrawImageUnscaled(drawing, new Point(0, 0));
            }
            else if(yellowCheck.Checked == true) /// yellow
            {
                Graphics panel = Graphics.FromImage(drawing);

                Pen pen = new Pen(Color.Yellow, penWidth);

                pen.EndCap = LineCap.Round;
                pen.StartCap = LineCap.Round;

                panel.DrawLine(pen, pX, pY, e.X, e.Y);

                transformedImage.CreateGraphics().DrawImageUnscaled(drawing, new Point(0, 0));
            }
            else /// green
            {
                Graphics panel = Graphics.FromImage(drawing);

                Pen pen = new Pen(Color.Green, penWidth);

                pen.EndCap = LineCap.Round;
                pen.StartCap = LineCap.Round;

                panel.DrawLine(pen, pX, pY, e.X, e.Y);

                transformedImage.CreateGraphics().DrawImageUnscaled(drawing, new Point(0, 0));
            }

        }

        pX = e.X;
        pY = e.Y;
    }

    private void transformedImage_MouseDown(object sender, MouseEventArgs e)
    {
        if (scratchCheck.Checked == true)
        {
            draw = true;
            pX = e.X;
            pY = e.Y;
        }
    }

    private void transformedImage_MouseUp(object sender, MouseEventArgs e)
    {
        draw = false;
    }

    private void transformedImage_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.DrawImageUnscaled(drawing, new Point(0, 0));  
    }

But when I saved image using this:

SaveFileDialog sfd = new SaveFileDialog();
                sfd.Title = "Select Save Location";
                sfd.InitialDirectory = @"Save_Path";
                sfd.AddExtension = true;
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    switch (Path.GetExtension(sfd.FileName).ToUpper())
                    {
                        case ".BMP":
                            bmp.Save(sfd.FileName, ImageFormat.Bmp);
                            break;
                        case ".gif":
                            bmp.Save(sfd.FileName, ImageFormat.Gif);
                            break;
                        case ".JPG":
                            bmp.Save(sfd.FileName, ImageFormat.Jpeg);
                            break;
                        case ".JPEG":
                            bmp.Save(sfd.FileName,ImageFormat.Jpeg);
                            break;
                        case ".PNG":
                            bmp.Save(sfd.FileName, ImageFormat.Png);
                            break;
                        case ".png":
                            bmp.Save(sfd.FileName, ImageFormat.Png);
                            break;
                        default:
                            break;
                    }
                }

The image scratched on picturebox was not scratched.

This is scratched image on picturebox before saving:

But when I saved using above code, the scratches were gone missing:

How to saved the picture along with the scratches?, Thank you very much.

解决方案

Two common errors:

  1. using CreateGraphics will not create persistent graphics. So: Alwas draw everything in the Paint event of the PictureBox! The MouseMove should only collect the points in a List<Point> or a List<List<Point>>. All drawing must happen in the Paint event using its e.Graphics object!

  2. The drawing on the surface only gets saved if you use DrawToBitmap to create a new bitmap, which will combine up to three layers: the BackgroundImage, the Image and all persistent drawings.

See here for an example of drawing and here for an example of using DrawToBitmap!

As an alternative to this recommended way of drawing over an Image you can also draw directly into it. This is what are actually doing in the MouseMove, but later you ignore the image and draw it in a non-persistent way.

Finally: The Save routine is saving a bmp whichyou have not shown us, so we can only conclude that it is the original Image you loaded.. Maybe drawing.Save(..) would help..

But there are so many issues with the code, that you really should do a complete rewrite, starting with the confusing names! (Hint: do not call an object the name of a different type, like Graphics panel!!!) And obviously a variable of type Pen or Color would also help avoiding those repetitions...

这篇关于在PictureBox C#上刮擦图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆