对于图片的分析以及C#代码对图片进行灰化与反转

来源:互联网 发布:淘宝搜索关键词优化 编辑:程序博客网 时间:2024/06/05 16:11

首先,在开始进行C#代码之前,我们需要对于图片的像素点有一个很好的了解。图片的分辨率是指每英寸含有的像素的个数,像素就是一个个的小点,每个像素都有不同的颜色值。单位面积内的像素越多,分辨率越高,图像的效果就越好。因为这些小点越紧凑,小店之间的距离越小,那么给人眼视觉的感觉就是越清楚。

 

一般小点之间是有距离的,但是这种距离要比像素点本身的长度小很多,所以,一张图片,如果使劲的放大,会发现有锯齿,也就是像素小点之间的距离能让人感觉到了。所以说,要让人视觉感受图片质量好,要么让小点更加紧凑,因为这样就感觉不到小点间的距离,要么就让人离图片远点,因为远了,人对于小点间的距离感受也就差了。这就是为什么户外广告屏幕的分辨率低,因为离得远,小点间的距离影响小,而手机或者电脑图片分辨率高,因为离得近。

 

这里需要注意,打印图片的时候,也会要求选择分辨率,这里的分辨率是打印分辨率,不是图片的分辨率。因为打印机每个单位能够打印的墨点是一样的,这时候你选择的分辨率越大,打出来的图片越长。

 

为什么低分辨率的图片在打印机上打印出来不清楚?因为打印机会分析这张图片,会看看有多少个像素点,然后把这些像素点平均分配到你所选择的打印尺寸上。当你选择的打印分辨率很高,也就是图片很大的时候,打印机把图片放大到相应的大小,然后用墨点模拟出这个图像,所以放大后有锯齿,打印出来依然有锯齿。

 

至于为什么有时候像素又成了尺寸单位?比如说写代码的时候,生成PDF的时候,像素又是尺寸单位。因为这时候屏幕每单位的像素点是一定的,所以像素越高,尺寸越大。

 

位图一般用于存储复杂的图形元素,比如说摄影。而矢量图虽然无限放大不会失真,但是用于表现过于复杂的图形相当吃力。一般用于表现绘图或者生成的线条等内容比较简单的图片。在电脑中存储的时候,像素点越多,那么图片的size就会越大。

 

好了,接下来进行C#代码的操作。其实,归根到底,对于图片的操作,就是对于图片每一个像素点的操作。我们可以使用C#代码获取这些像素点,然后对于每一个像素点的颜色进行操作。最终,会让这个图片整体上进行改变。

 

这里是一个WinForm的小程序,图片处理效果如图所示,这是图片灰化后的效果,与反转后的效果。








其代码实现也很简单。

public partial class Main : Form    {        private Image imageFile;        private bool opened = false;        private Bitmap bitMap;        public Main()        {            InitializeComponent();        }        private void button1_Click(object sender, EventArgs e)        {            Console.WriteLine("Click!");            DialogResult dr = openFileDialog.ShowDialog();            if (dr == DialogResult.OK)            {                imageFile = Image.FromFile(openFileDialog.FileName);                pictureBox.Image = imageFile;                opened = true;                bitMap = new Bitmap(imageFile);            }        }        private void buttonSave_Click(object sender, EventArgs e)        {            DialogResult dr = saveFileDialog.ShowDialog();            if (dr == DialogResult.OK && opened)            {                if (openFileDialog.FileName.Substring(openFileDialog.FileName.Length - 3).ToLower() == "png")                {                    imageFile.Save(saveFileDialog.FileName + ".png", ImageFormat.Png);                }            }        }        private void buttonGray_Click(object sender, EventArgs e)        {            for (int i = 0; i < bitMap.Width; i++)            {                for (int j = 0; j < bitMap.Height; j++)                {                    Color origalColor = bitMap.GetPixel(i, j);                    int grayScale = (int) (origalColor.R*.3 + origalColor.G*.59 + origalColor.B*.11);                    Color newColor = Color.FromArgb(grayScale, grayScale, grayScale);                    bitMap.SetPixel(i,j, newColor);                }            }            DialogResult dr = saveFileDialog.ShowDialog();            if (dr == DialogResult.OK)            {                bitMap.Save(saveFileDialog.FileName + ".png", ImageFormat.Png);                imageFile = Image.FromFile(saveFileDialog.FileName + ".png");                pictureBox.Image = imageFile;                pictureBox.Refresh();            }           }        private void buttonInvert_Click(object sender, EventArgs e)        {            for (int i = 0; i < bitMap.Width; i++)            {                for (int j = 0; j < bitMap.Height; j++)                {                    Color origalColor = bitMap.GetPixel(i, j);                    Color newColor = Color.FromArgb(255 -origalColor.R, 255-origalColor.G, 255-origalColor.B);                    bitMap.SetPixel(i, j, newColor);                }            }            DialogResult dr = saveFileDialog.ShowDialog();            if (dr == DialogResult.OK)            {                bitMap.Save(saveFileDialog.FileName + ".png", ImageFormat.Png);                imageFile = Image.FromFile(saveFileDialog.FileName + ".png");                pictureBox.Image = imageFile;                pictureBox.Refresh();                bitMap = new Bitmap(imageFile);            }        }    }}

最核心的代码就是下边这段代码,通过双重的for循环,获取每一个点,然后进行操作。至于灰化过程中,为什么是将RGB的每一个点的值取出来然后乘以相应的一些数如0.3,0.59等等,这个是从网上找的,估计不属于程序员的范畴,专业的作图着估计知道怎么转化才能达到某种效果。

for (int i = 0; i < bitMap.Width; i++){    for (int j = 0; j < bitMap.Height; j++)    {         Color origalColor = bitMap.GetPixel(i, j);         int grayScale = (int) (origalColor.R*.3 + origalColor.G*.59 + origalColor.B*.11);         Color newColor = Color.FromArgb(grayScale, grayScale, grayScale);         bitMap.SetPixel(i,j, newColor);    } }



1 0
原创粉丝点击