C#图像处理学习笔记(屏幕截取,打开保存图像、旋转图像、黑白、马赛克、降低亮度、浮雕)

1、创建Form窗体应用程序

         打开VS,创建新项目-语言选择C#-Window窗体应用(.NET Framework)

         如果找不到,检查一下有没有安装.NET 桌面开发模块,如果没有,需要下载,记得勾选相关开发工具

         接上一步,选择windows窗体应用程序之后,点击下一步,修改相关路径和名字之后,点击创建。就可以得到一个如下的form设计界面。

 2、使用到的程序包和控件
        2.1、程序包

                使用到Nuget程序包中的System.Drawing.Common,下载方式如下:

        2.2、控件

                通过视图-工具箱,把工具箱调出来,在工具箱选择需要的控件。

        1)、此功能会运用openFileDialog、saveFileDialog、Button、Picturebox、label控件

        2)、在Form设计界面布置界面,加入图片文件的Picturebox1控件,处理图片后显示图片的Picturebox2控件。 

        3)、一个openFileDialog控件,两个saveFileDialog控件

        4)、接下来布置按钮,Button1:“打开”,Button2:“保存”,Button3:“添加暗角”,Button4:“降低亮度”,Button5:“去色”,Button6:“浮雕”,Button7:“马赛克”,Button8:“扩散”,Button9:“清除图片”,Button10:“保存2”,Button11:“油画效果”,Button12:“柔化”,Button13:“截屏”,Button14:“旋转90”。

        5)、label控件。改名为:运行时间

        提示:右键控件属性,即可改名

界面如下:

 3、代码实现
        3.1、Button1打开按钮
   //打开按钮private void button1_Click(object sender, EventArgs e){if (openFileDialog1.ShowDialog() == DialogResult.OK){//获取打开文件的路径string path = openFileDialog1.FileName;bitmap = (Bitmap) Bitmap.FromFile(path);pictureBox1.Image = bitmap.Clone() as Image;}}
         3.2、Button2保存按钮
    //保存按钮private void button2_Click(object sender, EventArgs e){bool isSvae = 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 格式");isSvae = false;break;}}//默认保存为jpg格式if(imgformat == null){imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;}if(isSvae){try{pictureBox2.Image.Save(fileName, imgformat);MessageBox.Show("图片保存成功!");}catch{MessageBox.Show("保存失败! 你还没有截取过图片或者图片已经清空!");}}}}}
        3.3、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;}}
        3.4、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;}
}
       3.5、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;}}
        3.6、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;}}
        3.7、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, avgGreed = 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;avgGreed += pixel.G;avgBlue += pixel.B;count++;}}//取平均值avgRed = avgRed / count;avgBlue = avgBlue / count;avgGreed = avgGreed / 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, avgGreed, avgBlue);newbitmap.SetPixel(x, y, newColor);}}    }}sw.Stop();label1.Text = "运行时间: " + sw.ElapsedMilliseconds.ToString();pictureBox2.Image = newbitmap.Clone() as Image;}}
         3.8、Button8扩散按钮
   //扩散按钮private void button8_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++){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){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;}}
        3.9、Button9清除图片按钮
 //清除图片按钮private void button9_Click(object sender, EventArgs e){pictureBox1.Image = null;pictureBox2.Image = null;}
         3.10、保存2按钮
//保存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);}
}
         3.11、Button11油画按钮
  //油画按钮private void button11_Click(object sender, EventArgs e){if (bitmap != null){newbitmap = bitmap.Clone() as Bitmap;//取得图片尺寸int width = newbitmap.Width;int height = newbitmap.Height;sw.Reset();sw.Restart();//产生随机数序列Random rnd = new Random();//取不同的值决定油画效果的不同程度int iModel = 2;int i = width - iModel;while (i > 1){int j = height - iModel;while (j > 1){int iPos = rnd.Next(100000) % iModel;//将该点的RGB值设置成附近iModel点之内的任一点Color color = newbitmap.GetPixel(i + iPos, j + iPos);newbitmap.SetPixel(i, j, color);j = j - 1;}i = i - 1;}sw.Stop();label1.Text = "运行时间: " + sw.ElapsedMilliseconds.ToString();pictureBox2.Image = newbitmap.Clone() as Image;}}
         3.12、Button12柔化按钮
    //柔化按钮private void button12_Click(object sender, EventArgs e){if (bitmap != null){newbitmap = bitmap.Clone() as Bitmap;//取得图片尺寸int width = newbitmap.Width;int height = newbitmap.Height;sw.Reset();sw.Restart();Color piexl;//高斯模板int[] Gauss = { 1, 2, 1, 2, 4, 2, 1, 2, 1 };for(int x = 1; x < width - 1; x++){for(int y = 1; y < height - 1; y++){int r = 0, g = 0, b = 0;int index = 0;for(int col = -1; col <= 1; col++){for (int row = -1; row <= 1; row++){piexl = newbitmap.GetPixel(x + row, y + col);r += piexl.R * Gauss[index];g += piexl.G * Gauss[index];b += piexl.B * Gauss[index];index++;}}r /= 16;g /= 16;b /= 16;//处理颜色溢出r = r > 255 ? 255 : r;r = r < 0 ? 0 : r;g = g > 255 ? 255 : g;g = g < 0 ? 0 : g;b = b > 255 ? 255 : b;b = b < 0 ? 0 : b;bitmap.SetPixel(x - 1, y -1, Color.FromArgb(r, g, b));}}sw.Stop();label1.Text = "运行时间: " + sw.ElapsedMilliseconds.ToString();pictureBox2.Image = newbitmap.Clone() as Image;}}
         3.13、Button13截屏按钮
struct POINT
{public Int32 x;public Int32 y;
}struct CURSORINFO
{public Int32 cbSize;public Int32 flags;public IntPtr hCursor;public POINT ptScreenPos;
}// 按指定尺寸对图像pic进行非拉伸缩放public static Bitmap shrinkTo(Image pic, Size S, Boolean cutting){//创建图像Bitmap tmp = new Bitmap(S.Width, S.Height);//按指定大小创建图像//绘制Graphics g = Graphics.FromImage(tmp);//从位图创建Graphics对象g.Clear(Color.FromArgb(0, 0, 0)); //清空Boolean mode = (float)pic.Width / S.Width > (float)pic.Height / S.Height;  //zoom缩放if (cutting) mode = !mode;  //裁剪缩放//计算zoom绘制区域if (mode){S.Height = (int)((float)pic.Height * S.Width / pic.Width);}else{S.Width = (int)((float)pic.Width * S.Height / pic.Height);}Point p = new Point((tmp.Width - S.Width) / 2, (tmp.Height - S.Height) / 2);g.DrawImage(pic, new Rectangle(p, S));return tmp;//返回构建的新图像}//根据文件拓展名,获取对应的存储类型public static ImageFormat getFormat(string filePath){ImageFormat format = ImageFormat.MemoryBmp;String Ext = System.IO.Path.GetExtension(filePath).ToLower();if (Ext.Equals(".png")) format = ImageFormat.Png;else if (Ext.Equals(".jpg") || Ext.Equals(".jpeg")) format = ImageFormat.Jpeg;else if (Ext.Equals(".bmp")) format = ImageFormat.Bmp;else if (Ext.Equals(".gif")) format = ImageFormat.Gif;else if (Ext.Equals(".ico")) format = ImageFormat.Icon;else if (Ext.Equals(".emf")) format = ImageFormat.Emf;else if (Ext.Equals(".exif")) format = ImageFormat.Exif;else if (Ext.Equals(".tiff")) format = ImageFormat.Tiff;else if (Ext.Equals(".wmf")) format = ImageFormat.Wmf;else if (Ext.Equals(".memorybmp")) format = ImageFormat.MemoryBmp;return format;}//保存图像pic到文件fileName中,指定图像保存格式public static void SaveToFile(Image pic, string fileName, bool replace, ImageFormat format){//若图像已存在,则删除if (System.IO.File.Exists(fileName) && replace){System.IO.File.Delete(fileName);}//若不存在则创建if (!System.IO.File.Exists(fileName)){if (format == null){format = getFormat(fileName); //根据拓展名获取图像的对应存储类型}if (format == ImageFormat.MemoryBmp){pic.Save(fileName);MessageBox.Show("图片保存成功!");}else{pic.Save(fileName, format);//按给定格式保存图像MessageBox.Show("图片保存成功!");}}}// 缩放icon为指定的尺寸,并保存到路径PathNamepublic static void saveImage(Image image, Size size, String PathName){Image tmp = shrinkTo(image, size, false);SaveToFile(tmp, PathName, true, null);}// 截取屏幕指定区域为Image,保存到路径savePath下,haveCursor是否包含鼠标private static Image getScreen(int x = 0, int y = 0, int width = -1, int height = -1, String savePath = "", bool haveCursor = true){if (width == -1){width = SystemInformation.VirtualScreen.Width + 1280;//虚拟屏幕界限}if (height == -1){height = SystemInformation.VirtualScreen.Height + 800;}Bitmap tmp = new Bitmap(width, height); //按指定大小创建位图Graphics g = Graphics.FromImage(tmp); //从位图创建Graphics对象g.CopyFromScreen(x, y, 0, 0, new Size(width, height)); //绘制// 绘制鼠标if (haveCursor){try{CURSORINFO pci;pci.cbSize = Marshal.SizeOf(typeof(CURSORINFO));GetCursorInfo(out pci);System.Windows.Forms.Cursor cur = new System.Windows.Forms.Cursor(pci.hCursor);cur.Draw(g, new Rectangle(pci.ptScreenPos.x, pci.ptScreenPos.y, cur.Size.Width, cur.Size.Height));}catch (Exception ex){// 若获取鼠标异常则不显示}}if (!savePath.Equals("")){saveImage(tmp, tmp.Size, savePath); // 保存到指定的路径下}return tmp;  //返回构建的新图像}private static void GetCursorInfo(out CURSORINFO pci){throw new NotImplementedException();}//截屏按钮private void button13_Click(object sender, EventArgs e){screen = getScreen();                       // 截取屏幕  pictureBox1.Image = screen;}
       
//旋转90度按钮 
private void button14_Click(object sender, EventArgs e){//获取需要旋转的图片//  Bitmap bmp = (Bitmap)screen;Bitmap bmp = (Bitmap)pictureBox1.Image;sw.Reset();sw.Restart();//向右90度旋转bmp.RotateFlip(RotateFlipType.Rotate270FlipXY);sw.Stop();label1.Text = "运行时间: " + sw.ElapsedMilliseconds.ToString();pictureBox2.Image = bmp.Clone() as Image;}

 补充:旋转使用了Image类的RotateFlip方法

4、运行结果 

        打开一张图片显示到pictureBox1中,然后点击相应的按钮,便会在pictureBox2中显示处理后的图片。

5、完整代码
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.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;namespace WindowsFormsApp1
{public partial class Form1 : Form{//创建一个新的位图private Bitmap bitmap,  newbitmap;private Stopwatch sw;//计算运行时间//截屏的图片Image screen;public Form1(){InitializeComponent();sw = new Stopwatch();}struct POINT{public Int32 x;public Int32 y;}struct CURSORINFO{public Int32 cbSize;public Int32 flags;public IntPtr hCursor;public POINT ptScreenPos;}private void label1_Click(object sender, EventArgs e){}//保存按钮private void button2_Click(object sender, EventArgs e){bool isSvae = 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 格式");isSvae = false;break;}}//默认保存为jpg格式if(imgformat == null){imgformat = System.Drawing.Imaging.ImageFormat.Jpeg;}if(isSvae){try{pictureBox2.Image.Save(fileName, imgformat);MessageBox.Show("图片保存成功!");}catch{MessageBox.Show("保存失败! 你还没有截取过图片或者图片已经清空!");}}}}}//打开按钮private void button1_Click(object sender, EventArgs e){if (openFileDialog1.ShowDialog() == DialogResult.OK){string path = openFileDialog1.FileName;bitmap = (Bitmap) Bitmap.FromFile(path);pictureBox1.Image = bitmap.Clone() as Image;}}//添加暗角按钮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 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, avgGreed = 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;avgGreed += pixel.G;avgBlue += pixel.B;count++;}}//取平均值avgRed = avgRed / count;avgBlue = avgBlue / count;avgGreed = avgGreed / 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, avgGreed, avgBlue);newbitmap.SetPixel(x, y, newColor);}}    }}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 button8_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++){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){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 button9_Click(object sender, EventArgs e){pictureBox1.Image = null;pictureBox2.Image = null;}//保存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);}}//油画按钮private void button11_Click(object sender, EventArgs e){if (bitmap != null){newbitmap = bitmap.Clone() as Bitmap;//取得图片尺寸int width = newbitmap.Width;int height = newbitmap.Height;sw.Reset();sw.Restart();//产生随机数序列Random rnd = new Random();//取不同的值决定油画效果的不同程度int iModel = 2;int i = width - iModel;while (i > 1){int j = height - iModel;while (j > 1){int iPos = rnd.Next(100000) % iModel;//将该点的RGB值设置成附近iModel点之内的任一点Color color = newbitmap.GetPixel(i + iPos, j + iPos);newbitmap.SetPixel(i, j, color);j = j - 1;}i = i - 1;}sw.Stop();label1.Text = "运行时间: " + sw.ElapsedMilliseconds.ToString();pictureBox2.Image = newbitmap.Clone() as Image;}}//柔化按钮private void button12_Click(object sender, EventArgs e){if (bitmap != null){newbitmap = bitmap.Clone() as Bitmap;//取得图片尺寸int width = newbitmap.Width;int height = newbitmap.Height;sw.Reset();sw.Restart();Color piexl;//高斯模板int[] Gauss = { 1, 2, 1, 2, 4, 2, 1, 2, 1 };for(int x = 1; x < width - 1; x++){for(int y = 1; y < height - 1; y++){int r = 0, g = 0, b = 0;int index = 0;for(int col = -1; col <= 1; col++){for (int row = -1; row <= 1; row++){piexl = newbitmap.GetPixel(x + row, y + col);r += piexl.R * Gauss[index];g += piexl.G * Gauss[index];b += piexl.B * Gauss[index];index++;}}r /= 16;g /= 16;b /= 16;//处理颜色溢出r = r > 255 ? 255 : r;r = r < 0 ? 0 : r;g = g > 255 ? 255 : g;g = g < 0 ? 0 : g;b = b > 255 ? 255 : b;b = b < 0 ? 0 : b;bitmap.SetPixel(x - 1, y -1, Color.FromArgb(r, g, b));}}sw.Stop();label1.Text = "运行时间: " + sw.ElapsedMilliseconds.ToString();pictureBox2.Image = newbitmap.Clone() as Image;}}/// 按指定尺寸对图像pic进行非拉伸缩放public static Bitmap shrinkTo(Image pic, Size S, Boolean cutting){//创建图像Bitmap tmp = new Bitmap(S.Width, S.Height);//按指定大小创建图像//绘制Graphics g = Graphics.FromImage(tmp);//从位图创建Graphics对象g.Clear(Color.FromArgb(0, 0, 0)); //清空Boolean mode = (float)pic.Width / S.Width > (float)pic.Height / S.Height;  //zoom缩放if (cutting) mode = !mode;  //裁剪缩放//计算zoom绘制区域if (mode){S.Height = (int)((float)pic.Height * S.Width / pic.Width);}else{S.Width = (int)((float)pic.Width * S.Height / pic.Height);}Point p = new Point((tmp.Width - S.Width) / 2, (tmp.Height - S.Height) / 2);g.DrawImage(pic, new Rectangle(p, S));return tmp;//返回构建的新图像}//根据文件拓展名,获取对应的存储类型public static ImageFormat getFormat(string filePath){ImageFormat format = ImageFormat.MemoryBmp;String Ext = System.IO.Path.GetExtension(filePath).ToLower();if (Ext.Equals(".png")) format = ImageFormat.Png;else if (Ext.Equals(".jpg") || Ext.Equals(".jpeg")) format = ImageFormat.Jpeg;else if (Ext.Equals(".bmp")) format = ImageFormat.Bmp;else if (Ext.Equals(".gif")) format = ImageFormat.Gif;else if (Ext.Equals(".ico")) format = ImageFormat.Icon;else if (Ext.Equals(".emf")) format = ImageFormat.Emf;else if (Ext.Equals(".exif")) format = ImageFormat.Exif;else if (Ext.Equals(".tiff")) format = ImageFormat.Tiff;else if (Ext.Equals(".wmf")) format = ImageFormat.Wmf;else if (Ext.Equals(".memorybmp")) format = ImageFormat.MemoryBmp;return format;}//保存图像pic到文件fileName中,指定图像保存格式public static void SaveToFile(Image pic, string fileName, bool replace, ImageFormat format){//若图像已存在,则删除if (System.IO.File.Exists(fileName) && replace){System.IO.File.Delete(fileName);}//若不存在则创建if (!System.IO.File.Exists(fileName)){if (format == null){format = getFormat(fileName); //根据拓展名获取图像的对应存储类型}if (format == ImageFormat.MemoryBmp){pic.Save(fileName);MessageBox.Show("图片保存成功!");}else{pic.Save(fileName, format);//按给定格式保存图像MessageBox.Show("图片保存成功!");}}}/// 缩放icon为指定的尺寸,并保存到路径PathNamepublic static void saveImage(Image image, Size size, String PathName){Image tmp = shrinkTo(image, size, false);SaveToFile(tmp, PathName, true, null);}// 截取屏幕指定区域为Image,保存到路径savePath下,haveCursor是否包含鼠标private static Image getScreen(int x = 0, int y = 0, int width = -1, int height = -1, String savePath = "", bool haveCursor = true){if (width == -1){width = SystemInformation.VirtualScreen.Width + 1280;//虚拟屏幕界限}if (height == -1){height = SystemInformation.VirtualScreen.Height + 800;}Bitmap tmp = new Bitmap(width, height); //按指定大小创建位图Graphics g = Graphics.FromImage(tmp); //从位图创建Graphics对象g.CopyFromScreen(x, y, 0, 0, new Size(width, height)); //绘制// 绘制鼠标if (haveCursor){try{CURSORINFO pci;pci.cbSize = Marshal.SizeOf(typeof(CURSORINFO));GetCursorInfo(out pci);System.Windows.Forms.Cursor cur = new System.Windows.Forms.Cursor(pci.hCursor);cur.Draw(g, new Rectangle(pci.ptScreenPos.x, pci.ptScreenPos.y, cur.Size.Width, cur.Size.Height));}catch (Exception ex){// 若获取鼠标异常则不显示}}if (!savePath.Equals("")){saveImage(tmp, tmp.Size, savePath); // 保存到指定的路径下}return tmp;  //返回构建的新图像}private static void GetCursorInfo(out CURSORINFO pci){throw new NotImplementedException();}//旋转90度按钮private void button14_Click(object sender, EventArgs e){//获取需要旋转的图片//  Bitmap bmp = (Bitmap)screen;Bitmap bmp = (Bitmap)pictureBox1.Image;sw.Reset();sw.Restart();//向右90度旋转bmp.RotateFlip(RotateFlipType.Rotate270FlipXY);sw.Stop();label1.Text = "运行时间: " + sw.ElapsedMilliseconds.ToString();pictureBox2.Image = bmp.Clone() as Image;}//截屏按钮private void button13_Click(object sender, EventArgs e){screen = getScreen();                       // 截取屏幕  pictureBox1.Image = screen;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/432884.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第四篇-着色器投影-接收阴影部分】

上一章中实现了体积渲染的光照与自阴影&#xff0c;那我们这篇来实现投影 回顾 勘误 在开始本篇内容之前&#xff0c;我已经对上一章中的内容的错误进行了修改。为了确保不会错过这些更正&#xff0c;同时也避免大家重新阅读一遍&#xff0c;我将在这里为大家演示一下修改的…

叉车司机信息权限采集系统,保障与优化叉车运输网络的安全

叉车司机信息权限采集系统可以通过监控司机的行车行为和车辆状况&#xff0c;实时掌握车辆位置和行驶路线&#xff0c;从而提高运输安全性&#xff0c;优化运输网络&#xff0c;降低事故风险。同时&#xff0c;该系统还可以通过对叉车司机信息和行车数据的分析&#xff0c;优化…

Flutter屏幕适配

我们可以根据下面有适配属性的Widget来进行屏幕适配 1.MediaQuery 通过它可以直接获得屏幕的大小&#xff08;宽度 / 高度&#xff09;和方向&#xff08;纵向 / 横向&#xff09; Size screenSize MediaQuery.of(context).size; double width screenSize.width; double h…

springboot异常(三):异常处理原理

&#x1f345;一、BasicErrorController ☘️1.1 描述 BasicErrorController是Springboot中默认的异常处理方法&#xff0c;无需额外的操作&#xff0c;当程序发生了异常之后&#xff0c;Springboot自动捕获异常&#xff0c;重新请求到BasicErrorController中&#xff0c;在B…

网络安全 DVWA通关指南 DVWA Stored Cross Site Scripting (存储型 XSS)

DVWA Stored Cross Site Scripting (存储型 XSS) 文章目录 DVWA Stored Cross Site Scripting (存储型 XSS)XSS跨站原理存储型 LowMediumHighImpossible 参考文献 WEB 安全靶场通关指南 相关阅读 Brute Force (爆破) Command Injection&#xff08;命令注入&#xff09; Cro…

Spring:项目中的统一异常处理和自定义异常

介绍异常的处理方式。在项目中&#xff0c;都会进行自定义异常&#xff0c;并且都是需要配合统一结果返回进行使用。 1.背景引入 &#xff08;1&#xff09;背景介绍 为什么要处理异常&#xff1f;如果不处理项目中的异常信息&#xff0c;前端访问我们后端就是显示访问失败的…

eslint-plugin-react的使用中,所出现的react版本警告

记一次使用eslint-plugin-react的警告 Warning: React version not specified in eslint-plugin-react settings. See https://github.com/jsx-eslint/eslint-plugin-react#configuration . 背景 我们在工程化项目中&#xff0c;常常会通过eslint来约束我们代码的一些统一格…

基于RPA+BERT的文档辅助“悦读”系统 | OPENAIGC开发者大赛高校组AI创作力奖

在第二届拯救者杯OPENAIGC开发者大赛中&#xff0c;涌现出一批技术突出、创意卓越的作品。为了让这些优秀项目被更多人看到&#xff0c;我们特意开设了优秀作品报道专栏&#xff0c;旨在展示其独特之处和开发者的精彩故事。 无论您是技术专家还是爱好者&#xff0c;希望能带给…

关于寻址方式的讨论

### 对话内容 **学生B&#xff08;ESFP&#xff09;**&#xff1a;老师&#xff0c;寻址方式听起来很复杂&#xff0c;能详细讲解一下吗&#xff1f;而且最好能举些具体例子&#xff01;&#x1f60a; **老师&#xff08;ENTP&#xff09;**&#xff1a;当然可以&#xff01;…

JVM(HotSpot):方法区(Method Area)

文章目录 一、内存结构图二、方法区定义三、内存溢出问题四、常量池与运行时常量池 一、内存结构图 1.6 方法区详细结构图 1.8方法区详细结构图 1.8后&#xff0c;方法区是JVM内存的一个逻辑结构&#xff0c;真实内存用的本地物理内存。 且字符串常量池从常量池中移入堆中。 …

蓝队技能-应急响应篇Web内存马查杀Spring框架型中间件型JVM分析Class提取

知识点&#xff1a; 1、应急响应-Web框架内存马-分析&清除 2、应急响应-Web中间件内存马-分析&清除 注&#xff1a;框架型内存马与中间件内存马只要网站重启后就清除了。 目前Java内存马具体分类&#xff1a; 1、传统Web应用型内存马 Servlet型内存马&#xff1a;…

vivado中除法器ip核的使用

看了很多博客&#xff0c;都没写清楚&#xff0c;害 我要实现 reg [9:0] a; 被除数 reg [16:0] b; 除数 wire [39:0] res; 结果 wire [15:0] real_shan; 要实现a/b 则如下这么配置 选择经过几个周期出结果 wire [39:0] res; // dly5 div_gen_0 div_gen_0_inst (.aclk(clk), …

精密制造的革新:光谱共焦传感器与工业视觉相机的融合

在现代精密制造领域&#xff0c;对微小尺寸、高精度产品的检测需求日益迫切。光谱共焦传感器凭借其非接触、高精度测量特性脱颖而出&#xff0c;而工业视觉相机则以其高分辨率、实时成像能力著称。两者的融合&#xff0c;不仅解决了传统检测方式在微米级别测量上的局限&#xf…

通过 LabVIEW 正则表达式读取数值(整数或小数)

在LabVIEW开发中&#xff0c;字符串处理是一个非常常见的需求&#xff0c;尤其是在处理包含复杂格式的数字时。本文通过一个具体的例子来说明如何利用 Match Regular Expression Function 和 Match Pattern Function 读取并解析字符串中的数字&#xff0c;并重点探讨这两个函数…

MyBatis<foreach>标签的用法与实践

foreach标签简介 实践 demo1 简单的一个批量更新&#xff0c;这里传入了一个List类型的集合作为参数&#xff0c;拼接到 in 的后面 &#xff0c;来实现一个简单的批量更新 <update id"updateVislxble" parameterType"java.util.List">update model…

计算机视觉学习路线

计算机视觉&#xff08;Computer Vision&#xff09;是计算机科学的一个重要分支&#xff0c;旨在使计算机能够理解和解释视觉数据。以下是一个详细的计算机视觉学习路线&#xff0c;帮你系统地掌握这个领域所需的知识和技能。 1. 基础数学和编程 在深入学习计算机视觉之前&…

希捷电脑硬盘好恢复数据吗?探讨可能性、方法以及注意事项

在数字化时代&#xff0c;数据已成为我们生活和工作中不可或缺的一部分。希捷电脑硬盘作为数据存储的重要设备&#xff0c;承载着大量的个人文件、工作资料以及珍贵回忆。然而&#xff0c;面对硬盘故障或误操作导致的数据丢失&#xff0c;许多用户不禁要问&#xff1a;希捷电脑…

毕业设计选题:基于ssm+vue+uniapp的鲜花销售小程序

开发语言&#xff1a;Java框架&#xff1a;ssmuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;M…

FLUX.1图像生成模型:AI工程师的实践与探索

文章目录 1 FLUX.1系列模型2 AI工程师的视角3 ComfyUI部署4 FLUX.1部署5 工作流6 面向未来 黑森林实验室&#xff08;Black Forest Labs&#xff09;研发的FLUX.1图像生成模型&#xff0c;以其120亿参数的庞大规模&#xff0c;正在重新定义图像生成技术的新标准。FLUX.1系列模型…

【TabBar嵌套Navigation案例-新特性页面-代码位置 Objective-C语言】

一、接下来,我们来说这个新特性页面 1.首先,看一下我们的示例程序,这里改一下,加一个叹号, command + R, 好,首先啊,这里边有一个新特性页面,当我这个程序是第一次安装、第一次运行、还有呢、就是当这个应用程序更新的时候,我应该去加载这个新特性页面, 然后呢,这…