您的位置:首页 > 编程语言 > C#

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

2015-12-14 12:51 344 查看
首先,在开始进行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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图片 c# .net