使用C#进行图像处理

本文转载连接: https://blog.csdn.net/wchstrife/article/details/78984735

使用C#进行图像处理
前言
之前一直认为图像处理是一件很高大上的事情,在一门选修课的课上遇到一个图像处理的作业,上手几个简单的图像处理的算法,也算是入了个最简单的门。 
界面简单而又丑陋,代码命名也比较随意,大家重点关注算法就好 
在这里一共实现了暗角、降低亮度、灰度、浮雕、马赛克、扩散六个算法。 
项目github地址:https://github.com/wchstrife/ImageProcessing

界面设计
这里使用的是VS2010,新建C#工程之后。在界面上画出 
- 2个pictureBox作为显示的图片的控件。 
- 6个button作为不同效果的触发器, 
- 2个button作为文件打开和保存的触发器, 
- 1个label负责展示运行时间。

文件打开与保存

这里主要就是调用了openFileDialog和openFileDialog,不具体说。 
打开文件:

private void button7_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string path = openFileDialog1.FileName;
                bitmap = (Bitmap)Image.FromFile(path);
                pictureBox1.Image = bitmap.Clone() as Image;
            }
        }

保存文件:

private void button8_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
                        {
                            this.pictureBox2.Image.Save(fileName, imgformat);
                            //MessageBox.Show("图片已经成功保存!");   
                        }
                        catch
                        {
                            MessageBox.Show("保存失败,你还没有截取过图片或已经清空图片!");
                        }
                    }
                }
            }
        }

添加暗角
暗角就是在图像的四角添加逐渐变黑的一个圈。

基本步骤:
计算顶点与中心的距离maxDistance
计算每个像素点与中心的距离distance
计算factor = distance / maxDistance
将当前像素点的颜色设置为 原颜色 * (1-factor)
效果图

private void button1_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();
                timer.Text = sw.ElapsedMilliseconds.ToString();
                pictureBox2.Image = newbitmap.Clone() as Image;               
            }
        }

降低亮度

基本步骤

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

效果图

private void button2_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();
                timer.Text = sw.ElapsedMilliseconds.ToString();
                pictureBox2.Image = newbitmap.Clone() as Image;
            }
        }

去色

基本步骤

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

效果图

private void button3_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();
                timer.Text = sw.ElapsedMilliseconds.ToString();
                pictureBox2.Image = newbitmap.Clone() as Image;
            }
        }

浮雕

基本步骤

浮雕效果就是把RGB三个颜色取反。 
具体的实现用255-当前颜色的分量

效果图

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)(255 - pixel.R);
                        green = (int)(255 -  pixel.G);
                        blue = (int)(255 - pixel.B);
                        newbitmap.SetPixel(x, y, Color.FromArgb(red, green, blue));
                    }
                }
                sw.Stop();
                timer.Text = sw.ElapsedMilliseconds.ToString();
                pictureBox2.Image = newbitmap.Clone() as Image;
            }
        }

马赛克

基本步骤

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

效果图

/**
         * 马赛克效果
         * 默认的效果为50格
         * */
        private void button5_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();
                timer.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;
                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();
                timer.Text = sw.ElapsedMilliseconds.ToString();
                pictureBox2.Image = newbitmap.Clone() as Image;
            }
        }


 

发布了6 篇原创文章 · 获赞 189 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/newbie_xymt/article/details/103687459