在PictureBox C#上刮擦图像 [英] Scratch Image on 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;
}
}
未刮开图片盒上刮擦的图像.
在保存之前,这是图片盒上的划痕图像:
但是当我使用上面的代码保存时,划痕丢失了:
如何保存图片和划痕?,非常感谢.
两个常见错误:
-
使用
CreateGraphics
不会创建永久图形.因此:Alwas在PictureBox
的Paint
事件中绘制了所有内容!MouseMove
应该仅收集List<Point>
或List<List<Point>>
中的点. 所有图形必须使用其e.Graphics
对象在Paint
事件中发生! -
仅当使用
DrawToBitmap
创建新的位图时,表面上的图形才会保存,该位图将合并最多 3层:BackgroundImage
,Image
以及所有永久性图形.
请参见此处以绘画为例,并在此处有关使用DrawToBitmap
!
作为推荐的绘制Image
方式的替代方法,您也可以直接将其绘制.这是MouseMove
中实际执行的操作,但是稍后您将忽略图像并以非持久方式绘制它.
最后:Save
例程正在保存您没有显示给我们的bmp
,因此我们只能得出结论,它是您加载的原始Image
.也许drawing.Save(..)
会有所帮助. >
但是代码有很多问题,您真的应该从令人困惑的名称开始完全重写! (提示:不要用不同类型的名称来命名对象,例如Graphics panel
!!!!)显然,类型为Pen
或Color
的变量也将有助于避免重复...
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:
using
CreateGraphics
will not create persistent graphics. So: Alwas draw everything in thePaint
event of thePictureBox
! TheMouseMove
should only collect the points in aList<Point>
or aList<List<Point>>
. All drawing must happen in thePaint
event using itse.Graphics
object!The drawing on the surface only gets saved if you use
DrawToBitmap
to create a new bitmap, which will combine up to three layers: theBackgroundImage
, theImage
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屋!