Winform制作图像处理软件(一)
使用winform制作桌面应用比较方便,但是在图像的处理上比较吃力,这也与我没有认真学习过它的图像、图形应用有关。小菜鸡想在寒假期间练习一下如何制作一个图像处理软件。
首先,对于设计,我比较随意,设计的结果如下:
这里对图像分为了4宫格,当然每个格所绑定的快捷工具栏必须相同。现在先对所完成的几个功能进行一下总结。
功能如图快捷工具栏所示:
一、导入图片,虽然导入图片是个简单操作,但这里要非常注意,如何使得打开的图片可以保存到原图中。虽然这个操作很正常,但如果不对代码进行改进,会造成出错。
详细代码如下:
public int Openpc(PictureBox pb)
{
string pictures = string.Empty;
openFileDialog1.Filter = "bmp文件(*.BMP)|*.BMP|jpg文件(*.JPG)|*.JPG|png文件(*.PNG)|*.PNG|ALL File(*.*)|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
pictures = openFileDialog1.FileName;
if (pb.Image == null)
{
Bitmap bitmap = new Bitmap(pictures); //在这里我们需要将相片先放在bitmap对象中。
int h = bitmap.Size.Height;
int w = bitmap.Size.Width;
Bitmap bitmap2 = new Bitmap(w,h,PixelFormat.Format16bppRgb555); //这里需要构造一张与打开图片同样大小的图片流对象。
Graphics draw = Graphics.FromImage(bitmap2);
draw.DrawImage(bitmap, 0, 0,w,h); //在这里使用DrawImage画图,目的是将图片暂存在bitmap2这个 Bitmap对象中,其中DrawImage(图像,起始位置x,起始位置y,介绍位置x,介绍位置y)
pb.Image = (Image)bitmap2;
openFileDialog1.Dispose(); //记得要对这几个对象进行释放
draw.Dispose();
bitmap.Dispose();
return 1;
}
else
{
MessageBox.Show("图片框非空,请先移除图片!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return 0;
}
}
return 0;
}
二、 以上操作是为了对保存友好,保存的代码如下:
public int Savepc(PictureBox pb)
{
if(pb.Image != null)
{
string filename = string.Empty;
saveFileDialog1.Filter = "bmp文件(*.BMP)|*.BMP|jpg文件(*.JPG)|*.JPG|png文件(*.PNG)|*.PNG|ALL File(*.*)|*.*";
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
filename = saveFileDialog1.FileName;
try //如果在打开的时候不对原图像进行释放,保存在同一个图像文件时将会出错。
{
pb.Image.Save(filename);
return 1;
}
catch(Exception ex)
{
MessageBox.Show("保存出错,无法保存", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return 0;
}
}
}
else
{
MessageBox.Show("图片框未空,无法保存!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return 0;
}
return 0;
}
三、移除图片较为简单:
public void Deleteimg(PictureBox pb, ref int f)
{
if(f == 1)
{
DialogResult result = MessageBox.Show("图片未保存,是否移除!", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
if(result == DialogResult.Yes)
{
pb.Image = null;
//pb.Dispose(); //注意不需要释放对象
f = 0;
}
}
else
{
pb.Image = null;
}
}
四、图片的缩放,使用的是鼠标的滚轮事件。由于picturebox在时间中不提供鼠标滚轮的绑定,这里需要在窗体初始化时对该事件进行绑定。如果需要用到比较多的图形框,建议自定义一个picturebox的对象,即可使用自定义的功能。
pictureBox1.MouseWheel += new MouseEventHandler(pictureBox1_MouseWheel);
缩放的速度可以自己调整。在这里我使用了每次放大或缩小百分之十的速度。
private void pictureBox1_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e)
{
cp = (PictureBox)sender;
if (e.Delta >= 0)
{
cp.Width = (int)(cp.Width * 1.1); //因为picturebox的宽和高都是int类型,所以需要强制转型。
cp.Height = (int)(cp.Height * 1.1);
}
else
{
cp.Width = (int)(cp.Width * 0.9);
cp.Height = (int)(cp.Height * 0.9);
}
}
五、对图片进行位移,位移也是基本功能之一,当然在这里的位移是对这个picturebox进行位移。同时位移也是为了更好地配合缩放功能。
//拖拽
bool isDrag = false; //首先要设计一个变量判断控件是否正在被拖到。
Point mouseDownPoint = Point.Empty; //位移后的鼠标落点也是需要定义的。
//将被拖动的控件
Control control; //当然还有被拖动的控件要放在控制中。
private void pictureBox1_MouseDown(object sender, MouseEventArgs e) //要绑定鼠标按下的事件
{
isDrag = true;
control = (PictureBox)sender;
if (e.Button == MouseButtons.Left) //鼠标的左键对控件进行拖到
{
mouseDownPoint = control.Location;
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e) //我们通过以上操作锁定控件后,即可移动。
{
if (isDrag)
{
Point mousePos = new Point(control.Location.X, control.Location.Y); //记录控件的位置
mousePos.Offset(e.X, e.Y); //按鼠标事件的速度移动焦点
mousePos.X -= this.control.Width / 2; //当然,鼠标位置重新落到图像中心
mousePos.Y -= this.control.Height / 2;
control.Location = mousePos; //对控件位置进行改变(将焦点移动到的位置赋给控件)
}
}
六、旋转,在这里只做了简单的图片旋转,使用RotateFlip()方法,但此方法并不能对图像进行任意角度的旋转。
private void 顺时针旋转90ToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
PictureBox box = (PictureBox)cp;
Bitmap bitmap = new Bitmap(box.Image);
bitmap.RotateFlip(RotateFlipType.Rotate90FlipNone); //90°的顺时针旋转。
box.Image = bitmap;
}
catch(Exception ex)
{
MessageBox.Show("图片框内无图片!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
在这里看一下已经实现的功能的展示:
接下来要开始实现截图和自由角度的旋转。