C#图像处理

前言:

在之前的博客中讲到了用C#实现直方图均衡化的具体过程,
直方图均衡化
由于学校课程要求,在之前的基础上我对之前的程序进行了版本的更新,
得到一个更加完整,美观的版本!

前后对比:

V1.0界面:
这里写图片描述
实现功能:直方图均衡化
V2.0界面:
这里写图片描述
实现功能:

  • 均衡化,暗角,马赛克,去色,底片,扩散,降低亮度,镜像;
  • 图片浏览;
  • 图片清除;
  • 动画启动。

代码文件结构:

这里写图片描述
1.关于程序的代码,views里存放的是两个窗体:

  • Start_Form为程序开始的启动界面;
  • Showpicture为浏览界面。

2.在Contorl文件夹里的Operation.cs,封装的是程序的主要功能的代码;

3.Form1为项目的主界面;

主要功能的实现:

整体来说:

将业务逻辑层的代码放在Contorl文件夹里的Operation.cs
这里写图片描述
然后在主界面Form1,的RadioButton的Checked事件进行调用,

            if(radioButton1.Checked == true)
            {
                newbitmap = Operation.Equalization(bitmap);
                if(newbitmap != null)pictureBox2.Image = newbitmap.Clone() as Image;
                //显示至pictureBox2
                else { MessageBox.Show("原始图片为空!", "提示:"); }
            }

以上代码为调用OperationEqualization方法,再将处理后图片显示在pictureBox2上。

均衡化

这个就不多说。直方图均衡化

暗角

暗角就是在图像的四角添加逐渐变黑的一个圈。
步骤:
计算顶点与中心的距离maxDistance
计算每个像素点与中心的距离distance
计算factor = distance / maxDistance
将当前像素点的颜色设置为 原颜色 * (1-factor)

        /// <summary>
        /// 暗角处理
        /// </summary>
        public static Bitmap Darkangle(Bitmap bitmap)
        {
            if (bitmap != null)
            {
                newbitmap = bitmap.Clone() as Bitmap;
                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));
                    }
                }
            }
            return newbitmap;
        }

效果:
这里写图片描述

马赛克

步骤:
马赛克的基本思想就是把一个像素点周围的点的像素取个平均,
然后把这些像素点的颜色设为这个平均值。
周围的像素点取的越多,马克赛的效果也就越明显。

        /// <summary>
        /// 马赛克处理
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public static Bitmap Mosaic(Bitmap bitmap)
        {
            if (bitmap != null)
            {
                newbitmap = bitmap.Clone() as Bitmap;
                int RIDIO = 30;//马赛克的尺度,默认为周围两个像素
                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);
                            }
                        }
                    }
                }
            }
            return newbitmap;
        }

效果:
胖虎他妈都看不出
这里写图片描述

去色

步骤:
去色也就是要把照片灰化,将照片的RGB调节为灰色的。
具体的就是要把当前像素点的颜色按下面的公式的调整
gary = 0.3 * R + 0.59 * G + 0.11 * B

        /// <summary>
        /// 去色
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public static Bitmap Decoloration(Bitmap bitmap)
        {
            if (bitmap != null)
            {
                newbitmap = bitmap.Clone() as Bitmap;
                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));
                    }
                }
            }
            return newbitmap;
        }

效果:
这里写图片描述

底片

步骤:
底片效果就是把RGB三个颜色取反。
具体的实现用255减当前颜色的分量

       /// <summary>
        /// 底片
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public static Bitmap Cameo(Bitmap bitmap)
        {
            if (bitmap != null)
            {
                newbitmap = bitmap.Clone() as Bitmap;
                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));
                    }
                }
            }
            return newbitmap;
        }

效果:
这里写图片描述

扩散

步骤:
类似于水墨在纸上的扩散。随机挑选一个临近的像素,将其设为自身颜色。
这里一定注意要随机取周围的像素。

        /// <summary>
        /// 扩散
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public static Bitmap Spread(Bitmap bitmap)
        {
            if (bitmap != null)
            {
                newbitmap = bitmap.Clone() as Bitmap;
                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));
                    }
                }
            }
            return newbitmap;
        }

效果:
这里写图片描述

降低亮度

步骤:
降低亮度就是设置当前像素的颜色为原来的一个小于1的系数,
要注意各颜色的分量不能超过255。这里我们选取0.6作为系数。

        /// <summary>
        /// 亮度降低
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public static Bitmap Light_Reduction(Bitmap bitmap)
        {
            if (bitmap != null)
            {
                newbitmap = bitmap.Clone() as Bitmap;
                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));
                    }
                }
            }
            return newbitmap;
        }

效果:
这里写图片描述

镜像

步骤:
直接调用BitmapRotateFlip方法。

        /// <summary>
        /// 翻转
        /// </summary>
        /// <param name="bitmap"></param>
        /// <returns></returns>
        public static Bitmap RotateFlip(Bitmap bitmap)
        {
            RotateFlipType rotateFlipType = RotateFlipType.Rotate180FlipY;
            newbitmap = bitmap.Clone() as Bitmap;
            newbitmap.RotateFlip(rotateFlipType);
            return newbitmap;
        }

效果:
这里写图片描述

浏览功能:

注意:
在一般窗体的控件的属性为Prviate,所以在Form1.cspictureBox1_DoubleClick事件中是不能调用到
showpicture.picture的,
其中showpicture中只有一个Name为picture的picturebox,
所以我们要在Showpicture.Designer.cs中将prviate System.Windows.Forms.PictureBox picture,的修饰符改为public。

        /// <summary>
        /// 双击浏览原始图片
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox1_DoubleClick(object sender, EventArgs e)
        {
            Showpicture showpicture = new Showpicture();
            showpicture.picture.Image = bitmap.Clone() as Image;
            showpicture.Height = bitmap.Height;
            showpicture.Width = bitmap.Width;
            showpicture.Show();
        }

清理图片:

就是对comboBox1.SelectedItem的处理

        /// <summary>
        /// 清理视图
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            if(comboBox1.SelectedItem.ToString() == "全部")
            {
                bitmap = null;
                newbitmap = null;
                Operation.newbitmap = null;
                pictureBox1.Image = null;
                pictureBox2.Image = null;
                MessageBox.Show("已全部清空!", "提示:");
            }
            else if (comboBox1.SelectedItem.ToString() == "原始图")
            {
                bitmap = null;
                pictureBox1.Image = null;
                MessageBox.Show("原始图已清空!", "提示:");
            }
            else
            {
                newbitmap = null;
                pictureBox2.Image = null;
                Operation.newbitmap = null;
                MessageBox.Show("处理图已清空!", "提示:");
            }


        }

渐入渐出的动画效果

实现我们点击启动程序的时候,有一个启动界面,一闪而过,然后进入主界面。
在程序启动时的启动窗口,有程序的封面图片,如何我调用类DLL动态链接库文件,实现了窗体的淡入和淡出;
以下为Start_Form启动界面的后台代码

        [DllImport("user32")]
        private static extern bool AnimateWindow(IntPtr hwnd, int dwTime, int dwFlags);
        private const int AW_HOR_POSITIVE = 0x0001;//自左向右显示窗口,该标志可以在滚动动画和滑动动画中使用。使用AW_CENTER标志时忽略该标志
        private const int AW_HOR_NEGATIVE = 0x0002;//自右向左显示窗口,该标志可以在滚动动画和滑动动画中使用。使用AW_CENTER标志时忽略该标志
        private const int AW_VER_POSITIVE = 0x0004;//自顶向下显示窗口,该标志可以在滚动动画和滑动动画中使用。使用AW_CENTER标志时忽略该标志
        private const int AW_VER_NEGATIVE = 0x0008;//自下向上显示窗口,该标志可以在滚动动画和滑动动画中使用。使用AW_CENTER标志时忽略该标志该标志
        private const int AW_CENTER = 0x0010;//若使用了AW_HIDE标志,则使窗口向内重叠;否则向外扩展
        private const int AW_HIDE = 0x10000;//隐藏窗口
        private const int AW_ACTIVE = 0x20000;//激活窗口,在使用了AW_HIDE标志后不要使用这个标志
        private const int AW_SLIDE = 0x40000;//使用滑动类型动画效果,默认为滚动动画类型,当使用AW_CENTER标志时,这个标志就被忽略
        private const int AW_BLEND = 0x80000;//使用淡入淡出效果
        private void Start_Form_Load(object sender, EventArgs e)
        {
            timer1.Start();//启动定时器
            timer1.Interval = 2000;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //定时时间到了处理事件
            //this.Hide();//隐藏本窗体
            AnimateWindow(this.Handle, 1500, AW_SLIDE | AW_HIDE | AW_BLEND);
            Form1 MainForm = new Form1();//实例化一个MainForm对象
            MainForm.Show();//显示窗体
            timer1.Stop();//定制定时器
        }

        private void Start_Form_FormClosing(object sender, FormClosingEventArgs e)
        {
            AnimateWindow(this.Handle, 2000, AW_SLIDE | AW_HIDE | AW_BLEND);
        }

这里写图片描述
动态图有点小问题。( ̄;( ̄ )

最后

到这里,小程序就完成了。
源码地址

猜你喜欢

转载自blog.csdn.net/define_lin/article/details/80685287