一、作业内容
编写一个C#程序,实现图像处理,即“添加暗角”、“降低亮度”、“清除图片”、“去色”、“马赛克”、“浮雕”、“扩散”等功能。
1、程序可以读取图片文件,并显示在Picturebox中。
2、程序应能够处理可能出现的异常,如文件不存在、文件读取错误等。
3. 程序应具有良好的用户界面,方便用户进行操作。
4. 程序应具有良好的兼容性,能在不同版本的C#中正常运行。
提示:此功能会运用openFileDialog、saveFileDialog、Button、Picturebox、label控件
此功能可以使用Nuget程序包中的System.Drawing.Common
二、作业目的
1、掌握基本图像处理技术:通过C#进行图像处理,可以掌握基本的图像处理技术,如图像的“显示”、“保存”、“添加暗角”、“降低亮度”、“清除图片”、“去色”、“马赛克”、“浮雕”、“扩散”等功能。这些技术对于理解图像的本质和特性,以及进行更高级的图像处理和分析至关重要。
2、C# P图作业需要编写程序来实现图像处理功能,这可以提高编程能力。在编写程序的过程中,需要掌握C#的语法、数据结构、算法等基础知识,并能够运用它们来解决实际问题。
3、培养问题解决能力:图像处理是一个复杂且富有挑战性的领域,涉及到许多实际问题和应用场景。通过C# P图作业,可以接触到这些问题,并学会如何运用所学知识来分析和解决它们。
4、了解图像处理在实际中的应用:图像处理技术在许多领域都有广泛的应用,如医学影像、安防监控、自动驾驶等。通过C# P图作业,可以了解图像处理在实际中的应用场景和需求,并思考如何将所学知识应用到这些领域中。
三、要点介绍
1、安装System.Drawing.Common NuGet包:在Visual Studio中,通过NuGet包管理器安装System.Drawing.Common。使用Nuget程序包中的System.Drawing.Common
2、在Form设计界面布置P图界面,如加入图片文件的Picturebox1控件,处理图片后显示图片的Picturebox2控件。
3、将openFileDialog控件,saveFileDialog控件拖入设计界面。
4、接下来布置按钮分布,Button1:“打开”,Button2:“保存”,Button3:“添加暗角”,Button4:“降低亮度”,Button5:“去色”,Button6:“浮雕”,Button7:“马赛克”,Button8:“扩散”,Button9:“清除图片”,Button10:“保存2”。
5、拖入label控件。改名为:运行时间
布置界面结果如下:
四、代码实现
编写Button1:“打开”按钮代码
namespace WinFormsAppP
{
public partial class Form1 : Form
{
// 创建一个新的位图
private Bitmap bitmap, newbitmap;
private Stopwatch sw;
public Form1()
{
InitializeComponent();
sw = new Stopwatch();
}
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string path = openFileDialog1.FileName;
// pictureBox1.ImageLocation = path;
bitmap = (Bitmap)Image.FromFile(path);
pictureBox1.Image = bitmap.Clone() as Image;
//pictureBox1.Image=Image.FromFile(path);
}
}
编写Button2:“保存”按钮代码
private void button2_Click(object sender, EventArgs e)
{
bool isSave = true;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
string fileName = saveFileDialog1.FileName.ToString();
if (fileName != "" && fileName != null)
{
string fileExtName = fileName.Substring(fileName.LastIndexOf(".") + 1).ToString();
System.Drawing.Imaging.ImageFormat imgformat = null;
if (fileExtName != "")
{
switch (fileExtName)
{
case "jpg":
imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;
break;
case "bmp":
imgformat = System.Drawing.Imaging.ImageFormat.Bmp;
break;
case "gif":
imgformat = System.Drawing.Imaging.ImageFormat.Gif;
break;
default:
MessageBox.Show("只能存取为: jpg,bmp,gif 格式");
isSave = false;
break;
}
}
//默认保存为JPG格式
if (imgformat == null)
{
imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;
}
if (isSave)
{
try
{
pictureBox2.Image.Save(fileName, imgformat);
MessageBox.Show("图片已经成功保存!");
}
catch
{
MessageBox.Show("保存失败,你还没有截取过图片或已经清空图片!");
}
}
}
}
}
编写Button3:“添加暗角”代码
private void button3_Click(object sender, EventArgs e)
{
if (bitmap != null)
{
newbitmap = bitmap.Clone() as Bitmap;
sw.Reset();
sw.Restart();
int width = newbitmap.Width;
int height = newbitmap.Height;
float cx = width / 2;
float cy = height / 2;
float maxDist = cx * cx + cy * cy;
float currDist = 0, factor;
Color pixel;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
currDist = ((float)i - cx) * ((float)i - cx) + ((float)j - cy) * ((float)j - cy);
factor = currDist / maxDist;
pixel = newbitmap.GetPixel(i, j);
int red = (int)(pixel.R * (1 - factor));
int green = (int)(pixel.G * (1 - factor));
int blue = (int)(pixel.B * (1 - factor));
newbitmap.SetPixel(i, j, Color.FromArgb(red, green, blue));
}
}
sw.Stop();
label1.Text = "运行时间:" + sw.ElapsedMilliseconds.ToString();
pictureBox2.Image = newbitmap.Clone() as Image;
}
}
编写Button4:“降低亮度”按钮代码
private void button4_Click(object sender, EventArgs e)
{
if (bitmap != null)
{
newbitmap = bitmap.Clone() as Bitmap;
sw.Reset();
sw.Restart();
Color pixel;
int red, green, blue;
for (int x = 0; x < newbitmap.Width; x++)
{
for (int y = 0; y < newbitmap.Height; y++)
{
pixel = newbitmap.GetPixel(x, y);
red = (int)(pixel.R * 0.6);
green = (int)(pixel.G * 0.6);
blue = (int)(pixel.B * 0.6);
newbitmap.SetPixel(x, y, Color.FromArgb(red, green, blue));
}
}
sw.Stop();
label1.Text = "运行时间:" + sw.ElapsedMilliseconds.ToString();
pictureBox2.Image = newbitmap.Clone() as Image;
}
}
编写Button5:“去色”按钮代码
private void button5_Click(object sender, EventArgs e)
{
if (bitmap != null)
{
newbitmap = bitmap.Clone() as Bitmap;
sw.Reset();
sw.Restart();
Color pixel;
int gray;
for (int x = 0; x < newbitmap.Width; x++)
{
for (int y = 0; y < newbitmap.Height; y++)
{
pixel = newbitmap.GetPixel(x, y);
gray = (int)(0.3 * pixel.R + 0.59 * pixel.G + 0.11 * pixel.B);
newbitmap.SetPixel(x, y, Color.FromArgb(gray, gray, gray));
}
}
sw.Stop();
label1.Text = "运行时间:" + sw.ElapsedMilliseconds.ToString();
pictureBox2.Image = newbitmap.Clone() as Image;
}
}
编写Button6:“浮雕”按钮代码
private void button6_Click(object sender, EventArgs e)
{
if (bitmap != null)
{
newbitmap = bitmap.Clone() as Bitmap;
sw.Reset();
sw.Restart();
Color pixel;
int red, green, blue;
for (int x = 0; x < newbitmap.Width; x++)
{
for (int y = 0; y < newbitmap.Height; y++)
{
pixel = newbitmap.GetPixel(x, y);
red = (int)(255 - pixel.R);
green = (int)(255 - pixel.G);
blue = (int)(255 - pixel.B);
newbitmap.SetPixel(x, y, Color.FromArgb(red, green, blue));
}
}
sw.Stop();
label1.Text = "运行时间:" + sw.ElapsedMilliseconds.ToString();
pictureBox2.Image = newbitmap.Clone() as Image;
}
}
编写Button7:“马赛克”按钮代码
private void button7_Click(object sender, EventArgs e)
{
if (bitmap != null)
{
newbitmap = bitmap.Clone() as Bitmap;
sw.Reset();
sw.Restart();
int RIDIO = 50;//马赛克的尺度,默认为周围两个像素
for (int h = 0; h < newbitmap.Height; h += RIDIO)
{
for (int w = 0; w < newbitmap.Width; w += RIDIO)
{
int avgRed = 0, avgGreen = 0, avgBlue = 0;
int count = 0;
//取周围的像素
for (int x = w; (x < w + RIDIO && x < newbitmap.Width); x++)
{
for (int y = h; (y < h + RIDIO && y < newbitmap.Height); y++)
{
Color pixel = newbitmap.GetPixel(x, y);
avgRed += pixel.R;
avgGreen += pixel.G;
avgBlue += pixel.B;
count++;
}
}
//取平均值
avgRed = avgRed / count;
avgBlue = avgBlue / count;
avgGreen = avgGreen / count;
//设置颜色
for (int x = w; (x < w + RIDIO && x < newbitmap.Width); x++)
{
for (int y = h; (y < h + RIDIO && y < newbitmap.Height); y++)
{
Color newColor = Color.FromArgb(avgRed, avgGreen, avgBlue);
newbitmap.SetPixel(x, y, newColor);
}
}
}
}
sw.Stop();
label1.Text = "运行时间:" + sw.ElapsedMilliseconds.ToString();
pictureBox2.Image = newbitmap.Clone() as Image;
}
}
编写Button8:“扩散”按钮代码
private void button8_Click_1(object sender, EventArgs e)
{
if (bitmap != null)
{
newbitmap = bitmap.Clone() as Bitmap;
sw.Reset();
sw.Restart();
Color pixel;
int red, green, blue;
//int flag = 0;
for (int x = 0; x < newbitmap.Width; x++)
{
for (int y = 0; y < newbitmap.Height; y++)
{
Random ran = new Random();
int RankKey = ran.Next(-5, 5);
if (x + RankKey >= newbitmap.Width || y + RankKey >= newbitmap.Height || x + RankKey < 0 || y + RankKey < 0)
{
//flag = 1;
continue;
}
pixel = newbitmap.GetPixel(x + RankKey, y + RankKey);
red = (int)(pixel.R);
green = (int)(pixel.G);
blue = (int)(pixel.B);
newbitmap.SetPixel(x, y, Color.FromArgb(red, green, blue));
}
}
sw.Stop();
label1.Text = "运行时间:" + sw.ElapsedMilliseconds.ToString();
pictureBox2.Image = newbitmap.Clone() as Image;
}
}
编写Button9:“清除图片”按钮代码
private void button9_Click(object sender, EventArgs e)
{
pictureBox1.Image = null; pictureBox2.Image = null;
}
编写Button10:“保存2”按钮代码
private void button10_Click(object sender, EventArgs e)
{
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
string path = saveFileDialog1.FileName;
ImageFormat imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;
pictureBox2.Image.Save(path, imgformat);
}
}
五、运行结果
六、设计思路与难点
设计思路:
1、安装System.Drawing.Common NuGet包:在Visual Studio中,通过NuGet包管理器安装System.Drawing.Common。使用Nuget程序包中的System.Drawing.Common
2、在Form设计界面布置P图界面,如加入图片文件的Picturebox1控件,处理图片后显示图片的Picturebox2控件。
3、将openFileDialog控件,saveFileDialog控件拖入设计界面。
4、接下来布置按钮分布,Button1:“打开”,Button2:“保存”,Button3:“添加暗角”,Button4:“降低亮度”,Button5:“去色”,Button6:“浮雕”,Button7:“马赛克”,Button8:“扩散”,Button9:“清除图片”,Button10:“保存2”。
5、拖入label控件。改名为:运行时间
难点:
1、在C#中进行图像处理通常需要借助图像处理库。不同的图像处理库有不同的使用方法和特点
2、完成C# P图作业需要一定的C#编程技能。如果编程基础薄弱,可能会遇到编程实现上的困难。
3、设计并实现一些有趣的图像处理应用。然而,这要求具备较高的编程和图像处理技能,并且需要投入较多的时间和精力来完成。
七、完整代码(代码的clone地址)
using Microsoft.VisualBasic.Devices;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFormsAppP
{
public partial class Form1 : Form
{
// 创建一个新的位图
private Bitmap bitmap, newbitmap;
private Stopwatch sw;
public Form1()
{
InitializeComponent();
sw = new Stopwatch();
}
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string path = openFileDialog1.FileName;
// pictureBox1.ImageLocation = path;
bitmap = (Bitmap)Image.FromFile(path);
pictureBox1.Image = bitmap.Clone() as Image;
//pictureBox1.Image=Image.FromFile(path);
}
}
private void button2_Click(object sender, EventArgs e)
{
bool isSave = true;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
string fileName = saveFileDialog1.FileName.ToString();
if (fileName != "" && fileName != null)
{
string fileExtName = fileName.Substring(fileName.LastIndexOf(".") + 1).ToString();
System.Drawing.Imaging.ImageFormat imgformat = null;
if (fileExtName != "")
{
switch (fileExtName)
{
case "jpg":
imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;
break;
case "bmp":
imgformat = System.Drawing.Imaging.ImageFormat.Bmp;
break;
case "gif":
imgformat = System.Drawing.Imaging.ImageFormat.Gif;
break;
default:
MessageBox.Show("只能存取为: jpg,bmp,gif 格式");
isSave = false;
break;
}
}
//默认保存为JPG格式
if (imgformat == null)
{
imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;
}
if (isSave)
{
try
{
pictureBox2.Image.Save(fileName, imgformat);
MessageBox.Show("图片已经成功保存!");
}
catch
{
MessageBox.Show("保存失败,你还没有截取过图片或已经清空图片!");
}
}
}
}
}
private void button3_Click(object sender, EventArgs e)
{
if (bitmap != null)
{
newbitmap = bitmap.Clone() as Bitmap;
sw.Reset();
sw.Restart();
int width = newbitmap.Width;
int height = newbitmap.Height;
float cx = width / 2;
float cy = height / 2;
float maxDist = cx * cx + cy * cy;
float currDist = 0, factor;
Color pixel;
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
currDist = ((float)i - cx) * ((float)i - cx) + ((float)j - cy) * ((float)j - cy);
factor = currDist / maxDist;
pixel = newbitmap.GetPixel(i, j);
int red = (int)(pixel.R * (1 - factor));
int green = (int)(pixel.G * (1 - factor));
int blue = (int)(pixel.B * (1 - factor));
newbitmap.SetPixel(i, j, Color.FromArgb(red, green, blue));
}
}
sw.Stop();
label1.Text = "运行时间:" + sw.ElapsedMilliseconds.ToString();
pictureBox2.Image = newbitmap.Clone() as Image;
}
}
private void button4_Click(object sender, EventArgs e)
{
if (bitmap != null)
{
newbitmap = bitmap.Clone() as Bitmap;
sw.Reset();
sw.Restart();
Color pixel;
int red, green, blue;
for (int x = 0; x < newbitmap.Width; x++)
{
for (int y = 0; y < newbitmap.Height; y++)
{
pixel = newbitmap.GetPixel(x, y);
red = (int)(pixel.R * 0.6);
green = (int)(pixel.G * 0.6);
blue = (int)(pixel.B * 0.6);
newbitmap.SetPixel(x, y, Color.FromArgb(red, green, blue));
}
}
sw.Stop();
label1.Text = "运行时间:" + sw.ElapsedMilliseconds.ToString();
pictureBox2.Image = newbitmap.Clone() as Image;
}
}
private void button5_Click(object sender, EventArgs e)
{
if (bitmap != null)
{
newbitmap = bitmap.Clone() as Bitmap;
sw.Reset();
sw.Restart();
Color pixel;
int gray;
for (int x = 0; x < newbitmap.Width; x++)
{
for (int y = 0; y < newbitmap.Height; y++)
{
pixel = newbitmap.GetPixel(x, y);
gray = (int)(0.3 * pixel.R + 0.59 * pixel.G + 0.11 * pixel.B);
newbitmap.SetPixel(x, y, Color.FromArgb(gray, gray, gray));
}
}
sw.Stop();
label1.Text = "运行时间:" + sw.ElapsedMilliseconds.ToString();
pictureBox2.Image = newbitmap.Clone() as Image;
}
}
private void button6_Click(object sender, EventArgs e)
{
if (bitmap != null)
{
newbitmap = bitmap.Clone() as Bitmap;
sw.Reset();
sw.Restart();
Color pixel;
int red, green, blue;
for (int x = 0; x < newbitmap.Width; x++)
{
for (int y = 0; y < newbitmap.Height; y++)
{
pixel = newbitmap.GetPixel(x, y);
red = (int)(255 - pixel.R);
green = (int)(255 - pixel.G);
blue = (int)(255 - pixel.B);
newbitmap.SetPixel(x, y, Color.FromArgb(red, green, blue));
}
}
sw.Stop();
label1.Text = "运行时间:" + sw.ElapsedMilliseconds.ToString();
pictureBox2.Image = newbitmap.Clone() as Image;
}
}
private void button7_Click(object sender, EventArgs e)
{
if (bitmap != null)
{
newbitmap = bitmap.Clone() as Bitmap;
sw.Reset();
sw.Restart();
int RIDIO = 50;//马赛克的尺度,默认为周围两个像素
for (int h = 0; h < newbitmap.Height; h += RIDIO)
{
for (int w = 0; w < newbitmap.Width; w += RIDIO)
{
int avgRed = 0, avgGreen = 0, avgBlue = 0;
int count = 0;
//取周围的像素
for (int x = w; (x < w + RIDIO && x < newbitmap.Width); x++)
{
for (int y = h; (y < h + RIDIO && y < newbitmap.Height); y++)
{
Color pixel = newbitmap.GetPixel(x, y);
avgRed += pixel.R;
avgGreen += pixel.G;
avgBlue += pixel.B;
count++;
}
}
//取平均值
avgRed = avgRed / count;
avgBlue = avgBlue / count;
avgGreen = avgGreen / count;
//设置颜色
for (int x = w; (x < w + RIDIO && x < newbitmap.Width); x++)
{
for (int y = h; (y < h + RIDIO && y < newbitmap.Height); y++)
{
Color newColor = Color.FromArgb(avgRed, avgGreen, avgBlue);
newbitmap.SetPixel(x, y, newColor);
}
}
}
}
sw.Stop();
label1.Text = "运行时间:" + sw.ElapsedMilliseconds.ToString();
pictureBox2.Image = newbitmap.Clone() as Image;
}
}
private void saveFileDialog2_FileOk(object sender, CancelEventArgs e)
{
}
private void button8_Click_1(object sender, EventArgs e)
{
if (bitmap != null)
{
newbitmap = bitmap.Clone() as Bitmap;
sw.Reset();
sw.Restart();
Color pixel;
int red, green, blue;
//int flag = 0;
for (int x = 0; x < newbitmap.Width; x++)
{
for (int y = 0; y < newbitmap.Height; y++)
{
Random ran = new Random();
int RankKey = ran.Next(-5, 5);
if (x + RankKey >= newbitmap.Width || y + RankKey >= newbitmap.Height || x + RankKey < 0 || y + RankKey < 0)
{
//flag = 1;
continue;
}
pixel = newbitmap.GetPixel(x + RankKey, y + RankKey);
red = (int)(pixel.R);
green = (int)(pixel.G);
blue = (int)(pixel.B);
newbitmap.SetPixel(x, y, Color.FromArgb(red, green, blue));
}
}
sw.Stop();
label1.Text = "运行时间:" + sw.ElapsedMilliseconds.ToString();
pictureBox2.Image = newbitmap.Clone() as Image;
}
}
private void button10_Click(object sender, EventArgs e)
{
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
string path = saveFileDialog1.FileName;
ImageFormat imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;
pictureBox2.Image.Save(path, imgformat);
}
}
private void button9_Click(object sender, EventArgs e)
{
pictureBox1.Image = null; pictureBox2.Image = null;
}
}
}