实现图象颜色反转这一简单效果可以使用ColorMatrix轻松实现,下面介绍这一实现过程!
第一步:打开原始图象
第二步:在内存中创建一个和原始图象同样尺寸的图象
第三步:创建一个转化矩阵,并建立其与ImageAttributes对象的联系
第四步:创建一个Graphics对象
第五步:利用Graphics对象的DrawImage方法将原始图象使用颜色矩阵绘制到在内存中的那个图象,以实现反转效果.
下面是我做的一个实验,实验效果图如下:
代码如下:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
namespace 用颜色矩阵类实现图象颜色的反转效果
{
/// <summary>
/// Form1 的摘要说明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.OpenFileDialog
openFileDialog1;
private System.Windows.Forms.Button button1;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components =
null;
public Form1()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
//
// TODO: 在 InitializeComponent 调用后添加任何
构造函数代码
//
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button2 = new System.Windows.Forms.Button
();
this.pictureBox1 = new
System.Windows.Forms.PictureBox();
this.openFileDialog1 = new
System.Windows.Forms.OpenFileDialog();
this.button1 = new System.Windows.Forms.Button
();
this.SuspendLayout();
//
// button2
//
this.button2.Enabled = false;
this.button2.Location = new
System.Drawing.Point(8, 24);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(40,
80);
this.button2.TabIndex = 1;
this.button2.Text = "反转";
this.button2.Click += new System.EventHandler
(this.button2_Click);
//
// pictureBox1
//
this.pictureBox1.BorderStyle =
System.Windows.Forms.BorderStyle.Fixed3D;
this.pictureBox1.Location = new
System.Drawing.Point(56, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new
System.Drawing.Size(272, 272);
this.pictureBox1.SizeMode =
System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.pictureBox1.TabIndex = 2;
this.pictureBox1.TabStop = false;
//
// openFileDialog1
//
this.openFileDialog1.FileOk += new
System.ComponentModel.CancelEventHandler(this.openFileDialog1_FileOk);
//
// button1
//
this.button1.Location = new
System.Drawing.Point(8, 160);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(40,
88);
this.button1.TabIndex = 3;
this.button1.Text = "打开";
this.button1.Click += new System.EventHandler
(this.button1_Click);
//
// Form1
//
this.AutoScaleBaseSize = new
System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(328,
278);
this.Controls.Add(this.button1);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.button2);
this.Name = "Form1";
this.Text = "用颜色矩阵类实现图象颜色的反转效果
";
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
try
{
Application.Run(new Form1());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button2_Click(object sender,
System.EventArgs e)
{
Image img = this.pictureBox1.Image;
Bitmap bm = new Bitmap(img.Width,img.Height);
Graphics g = Graphics.FromImage(bm);
//ColorMatrix cm = new ColorMatrix(new float[][]{ new
float[]{0.3f,0.3f,0.3f,0,0},
//new float[]{0.59f,0.59f,0.59f,0,0},
//new float[]{0.11f,0.11f,0.11f,0,0},
// new float[]{0,0,0,1,0,0},
// new float[]{0,0,0,0,1,0},
// new float[]{0,0,0,0,0,1}});
//用这个可以实现灰度效果!
//Gilles Khouzams colour corrected grayscale shear
ColorMatrix cm = new ColorMatrix(new float[][]{ new float[]{-1,0,0,0,0,0},
new float[]{0,-1,0,0,0},
new float[]{0,0,-1,0,0},
new float[]{0,0,0,1,0,0},
new float[]{0,0,0,0,1,0},
new float[]{0,0,0,0,0,1}});
ImageAttributes ia = new ImageAttributes();
ia.SetColorMatrix(cm);
g.DrawImage(img,new Rectangle(0,0,img.Width,img.Height),0,0,img.Width,img.Height,GraphicsUnit.Pixel,ia);
g.Dispose();
this.pictureBox1.Image=bm;
}
private void openFileDialog1_FileOk(object sender,
System.ComponentModel.CancelEventArgs e)
{
}
private void button1_Click(object sender,
System.EventArgs e)
{
openFileDialog1=new OpenFileDialog();
openFileDialog1.Filter = "Bitmap文件(*.bmp)
|*.bmp|jpeg文件(*.jpg)|*.jpg|所有合适文件(*.BMP;*.JPG)|*.BMP;*.JPG";
openFileDialog1.FilterIndex = 2 ;
openFileDialog1.RestoreDirectory = true ;
if(DialogResult.OK ==
openFileDialog1.ShowDialog())
{
pictureBox1.Image=Bitmap.FromFile
(openFileDialog1.FileName,false);
}
button2.Enabled=true;
}
}
}
想要说明的是,利用颜色矩阵还可以实现很多功能,比如灰度效果、亮度变化等!我在文中已经列举了灰度效果的代码,大家可以替换下看下效果!
还有点说明:
我在实验中发现,这个方法有个问题,就是对于某些像素,反转前后会有明显的变化。我想了想这个原因,应该是这样,如果像素的信息是(192,168,0)或者是别的但要包含0,这种情况下,经过颜色矩阵的变化,含0部分将还是0,因为0与-1相乘的结果还是0,而不是我们所希望的255,这样,使得有些像素信息不是我们反转后所要求的。我想了想,这个方法还要改正,希望各位朋友能提供思路。或者我想出来会第一时间告诉大家!
浙公网安备 33010602011771号