工程雖然老點(diǎn),但里面的各種算法還是可以使用一下,很多圖像的處理算法,自己寫(xiě)了一個(gè)C#圖像處理的例子。這個(gè)DEMO的界面的有兩個(gè)PictrueBox控件,用來(lái)顯示圖片,一個(gè)是源圖片,一個(gè)是經(jīng)過(guò)轉(zhuǎn)換的目標(biāo)圖片,UI下面部分有一些按鈕,每個(gè)按鈕實(shí)現(xiàn)一個(gè)轉(zhuǎn)換功能。這個(gè)DEMO允許用戶拖一張圖片到源PictureBox中,然后通過(guò)這些功能按鈕實(shí)現(xiàn)圖片的效果轉(zhuǎn)換。這些功能有把圖片變成黑白、底片、浮雕、銳化、柔化等效果。
效果圖如下:
首先來(lái)一張運(yùn)行效果圖:
這個(gè)DEMO主要有以下幾個(gè)機(jī)能點(diǎn):
圖像處理
PictureBox的拖拽。
計(jì)算處理時(shí)間
對(duì)圖像進(jìn)行縮放處理
1.圖像處理
首先說(shuō)明一點(diǎn),圖像處理的算法不是我自己的想出來(lái)的,也沒(méi)有必要去想,網(wǎng)上調(diào)查一下,很多的。所以算法是網(wǎng)是找的。在些聲明一下。
1.1 黑白效果
原理: 彩色圖像處理成黑白效果通常有3種算法:
(1).最大值法: 使每個(gè)像素點(diǎn)的 R, G, B 值等于原像素點(diǎn)的 RGB (顏色值) 中最大的一個(gè);
(2).平均值法: 使用每個(gè)像素點(diǎn)的 R,G,B值等于原像素點(diǎn)的RGB值的平均值;
(3).加權(quán)平均值法: 對(duì)每個(gè)像素點(diǎn)的 R, G, B值進(jìn)行加權(quán),R,G,B的系數(shù)分別是0.7,0.2,0.1。
自認(rèn)為第三種的效果是最好的。
1.2 底片效果
原理: GetPixel方法獲得每一點(diǎn)像素的值, 然后再使用SetPixel方法將取反后的顏色值設(shè)置到對(duì)應(yīng)的點(diǎn)。
1.3 銳化效果
原理:突出顯示顏色值大(即形成形體邊緣)的像素點(diǎn)。
1.4 浮雕效果
原理: 對(duì)圖像像素點(diǎn)的像素值分別與相鄰像素點(diǎn)的像素值相減后加上128, 然后將其作為新的像素點(diǎn)的值。
1.5 柔化效果
原理: 當(dāng)前像素點(diǎn)與周圍像素點(diǎn)的顏色差距較大時(shí)取其平均值。
2.PictureBox的拖拽
拖拽是寫(xiě)在UserControlPictureBox類中,該類繼承于UserControl,里面有一個(gè)PictrueBox,相當(dāng)于把圖片顯示,縮放,拖拽封裝了。
C#的拖拽還是很簡(jiǎn)單的。主要用到DragEnter和DragDrop事件和DoDragDrop方法。
DragEnter
在拖拽源被拖入到拖拽目標(biāo)時(shí)觸發(fā),在這個(gè)事件處理函數(shù)中,要做的事情就是設(shè)置DragEventArgs 對(duì)象的Effect,這是一個(gè)DragDropEffects枚舉值。具體請(qǐng)參見(jiàn)MSDN。
DragDrop
在釋放鼠標(biāo)并且鼠標(biāo)拖拽目標(biāo)之內(nèi)在時(shí)發(fā)生。這里面可以接受拖拽的數(shù)據(jù)。
DoDragDrop
這個(gè)函數(shù)表示開(kāi)始一個(gè)拖拽事件,一般是在MouseDown或者M(jìn)ouseMove中調(diào)用這個(gè)函數(shù),這個(gè)函數(shù)會(huì)阻塞線程。
3.計(jì)算處理時(shí)間
這部分主要用到了QueryPerformanceCounter 和 QueryPerformanceFrequency API。這里會(huì)涉及到API與C#交互的問(wèn)題。代碼如下:
[csharp] view plaincopy
[DllImport("kernel32.dll")]
private static extern bool QueryPerformanceCounter(ref long lpPerformanceCount);
[DllImport("kernel32.dll")]
private static extern bool QueryPerformanceFrequency(ref long lpFrequency);
4.對(duì)圖像進(jìn)行縮放處理
這部分是也是寫(xiě)在UserControlPictureBox類中。由于用戶拖入的圖片尺寸可能很大,顯示在PictrueBox中雖說(shuō)可以進(jìn)行縮放顯示,但得到的Image對(duì)象還是原來(lái)圖片你的尺寸,所以為了提高轉(zhuǎn)換效率,就要對(duì)圖片進(jìn)行等比例縮放。核心代碼如下:
[cpp] view plaincopy
Bitmap bitmap = new Bitmap(newWidth, newHeight, oldImage.PixelFormat);
Graphics g = Graphics.FromImage(bitmap);
g.Clear(Color.Transparent);
g.DrawImage(oldImage, new RectangleF(0, 0, newWidth, newHeight));
return Image.FromHbitmap(bitmap.GetHbitmap());
其中newWidth, newHeight是新的圖片的尺寸,這兩個(gè)值的得到很簡(jiǎn)單。
5.總體說(shuō)明
界面上有很多按鈕,其實(shí)每個(gè)按鈕的事件處理程序都是一個(gè),我在程序中定義了一個(gè)枚舉:
[csharp] view plaincopy
public enum ImageEffect
{
GrayScale = 0, // 黑白
Film = 1, // 底片
Relief = 2, // 浮雕
Soften = 3, // 柔化
Sharpen = 4, // 銳化
Canvas = 5, // 油畫(huà)
}
在按鈕處理程序中根據(jù)不同的按鈕ID,給ImageEffectManager類的ChangeEffect方法傳遞不同的參數(shù)。
一、各種旋轉(zhuǎn)、改變大小
注意:先要添加畫(huà)圖相關(guān)的using引用。
//向右旋轉(zhuǎn)圖像90°代碼如下:
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
Bitmap bmp = new Bitmap("rama.jpg");//加載圖像
g.FillRectangle(Brushes.White, this.ClientRectangle);//填充窗體背景為白色
Point[] destinationPoints = {
new Point(100, 0), // destination for upper-left point of original
new Point(100, 100),// destination for upper-right point of original
new Point(0, 0)}; // destination for lower-left point of original
g.DrawImage(bmp, destinationPoints);
}
//旋轉(zhuǎn)圖像180°代碼如下:
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
Bitmap bmp = new Bitmap("rama.jpg");
g.FillRectangle(Brushes.White, this.ClientRectangle);
Point[] destinationPoints = {
new Point(0, 100), // destination for upper-left point of original
new Point(100, 100),// destination for upper-right point of original
new Point(0, 0)}; // destination for lower-left point of original
g.DrawImage(bmp, destinationPoints);
}
//圖像切變代碼:
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
Bitmap bmp = new Bitmap("rama.jpg");
g.FillRectangle(Brushes.White, this.ClientRectangle);
Point[] destinationPoints = {
new Point(0, 0), // destination for upper-left point of original
new Point(100, 0), // destination for upper-right point of original
new Point(50, 100)};// destination for lower-left point of original
g.DrawImage(bmp, destinationPoints);
}
//圖像截取:
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
Bitmap bmp = new Bitmap("rama.jpg");
g.FillRectangle(Brushes.White, this.ClientRectangle);
Rectangle sr = new Rectangle(80, 60, 400, 400);//要截取的矩形區(qū)域
Rectangle dr = new Rectangle(0, 0, 200, 200);//要顯示到Form的矩形區(qū)域
g.DrawImage(bmp, dr, sr, GraphicsUnit.Pixel);
}
//改變圖像大小:
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
Bitmap bmp = new Bitmap("rama.jpg");
g.FillRectangle(Brushes.White, this.ClientRectangle);
int width = bmp.Width;
int height = bmp.Height;
// 改變圖像大小使用低質(zhì)量的模式
g.InterpolationMode = InterpolationMode.NearestNeighbor;
g.DrawImage(bmp, new Rectangle(10, 10, 120, 120), // source rectangle
new Rectangle(0, 0, width, height), // destination rectangle
GraphicsUnit.Pixel);
// 使用高質(zhì)量模式
//g.CompositingQuality = CompositingQuality.HighSpeed;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(
bmp,
new Rectangle(130, 10, 120, 120),
new Rectangle(0, 0, width, height),
GraphicsUnit.Pixel);
}
//設(shè)置圖像的分辯率:
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
Bitmap bmp = new Bitmap("rama.jpg");
g.FillRectangle(Brushes.White, this.ClientRectangle);
bmp.SetResolution(300f, 300f);
g.DrawImage(bmp, 0, 0);
bmp.SetResolution(1200f, 1200f);
g.DrawImage(bmp, 180, 0);
}
//用GDI+畫(huà)圖
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics gForm = e.Graphics;
gForm.FillRectangle(Brushes.White, this.ClientRectangle);
for (int i = 1; i <= 7; ++i)
{
//在窗體上面畫(huà)出橙色的矩形
Rectangle r = new Rectangle(i*40-15, 0, 15,
this.ClientRectangle.Height);
gForm.FillRectangle(Brushes.Orange, r);
}
//在內(nèi)存中創(chuàng)建一個(gè)Bitmap并設(shè)置CompositingMode
Bitmap bmp = new Bitmap(260, 260,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Graphics gBmp = Graphics.FromImage(bmp);
gBmp.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
// 創(chuàng)建一個(gè)帶有Alpha的紅色區(qū)域
// 并將其畫(huà)在內(nèi)存的位圖里面
Color red = Color.FromArgb(0x60, 0xff, 0, 0);
Brush redBrush = new SolidBrush(red);
gBmp.FillEllipse(redBrush, 70, 70, 160, 160);
// 創(chuàng)建一個(gè)帶有Alpha的綠色區(qū)域
Color green = Color.FromArgb(0x40, 0, 0xff, 0);
Brush greenBrush = new SolidBrush(green);
gBmp.FillRectangle(greenBrush, 10, 10, 140, 140);
//在窗體上面畫(huà)出位圖 now draw the bitmap on our window
gForm.DrawImage(bmp, 20, 20, bmp.Width, bmp.Height);
// 清理資源
bmp.Dispose();
gBmp.Dispose();
redBrush.Dispose();
greenBrush.Dispose();
}
//在窗體上面繪圖并顯示圖像
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
Pen blackPen = new Pen(Color.Black, 1);
if (ClientRectangle.Height / 10 > 0)
{
for (int y = 0; y < ClientRectangle.Height; y += ClientRectangle.Height / 10)
{
g.DrawLine(blackPen, new Point(0, 0), new Point(ClientRectangle.Width, y));
}
}
blackPen.Dispose();
}
C# 使用Bitmap類進(jìn)行圖片裁剪
在Mapwin(手機(jī)游戲地圖編輯器)生成的地圖txt文件中添加自己需要處理的數(shù)據(jù)后轉(zhuǎn)換成可在手機(jī)(Ophone)開(kāi)發(fā)環(huán)境中使用的字節(jié)流地圖文件的小工具,其中就涉及到圖片的裁剪和生成了。有以下幾種方式。
方法一:拷貝像素。
當(dāng)然這種方法是最笨的,效率也就低了些。
在Bitmap類中我們可以看到這樣兩個(gè)方法:GetPixel(int x, int y)和SetPixel(int x, int y, Color color)方法。從字面的含以上就知道前者是獲取圖像某點(diǎn)像素值,是用Color對(duì)象返回的;后者是將已知像素描畫(huà)到制定的位置。
下面就來(lái)做個(gè)實(shí)例檢驗(yàn)下:
1.首先創(chuàng)建一個(gè)Windows Form窗體程序,往該窗體上拖放7個(gè)PictureBox控件,第一個(gè)用于放置并顯示原始的大圖片,其后6個(gè)用于放置并顯示裁剪后新生成的6個(gè)小圖;
2.放置原始大圖的PictureBox控件name屬性命名為pictureBoxBmpRes,其后pictureBox1到pictureBox6依次命名,并放置在合適的位置;
3.雙擊Form窗體,然后在Form1_Load事件中加入下面的代碼即可。
//導(dǎo)入圖像資源
Bitmap bmpRes = null;
String strPath = Application.ExecutablePath;
try{
int nEndIndex = strPath.LastIndexOf('//');
strPath = strPath.Substring(0,nEndIndex) + "//Bmp//BmpResMM.bmp";
bmpRes = new Bitmap(strPath);
//窗體上顯示加載圖片
pictureBoxBmpRes.Width = bmpRes.Width;
pictureBoxBmpRes.Height = bmpRes.Height;
pictureBoxBmpRes.Image = bmpRes;
}
catch(Exception ex)
{
System.Windows.Forms.MessageBox.Show("圖片資源加載失。/r/n" + ex.ToString());
}
//裁剪圖片(裁成2行3列的6張圖片)
int nYClipNum = 2, nXClipNum = 3;
Bitmap[] bmpaClipBmpArr = new Bitmap[nYClipNum * nXClipNum];
for (int nYClipNumIndex = 0; nYClipNumIndex < nYClipNum; nYClipNumIndex++)
{
for (int nXClipNumIndex = 0; nXClipNumIndex < nXClipNum; nXClipNumIndex++)
{
int nClipWidth = bmpRes.Width / nXClipNum;
int nClipHight = bmpRes.Height / nYClipNum;
int nBmpIndex = nXClipNumIndex + nYClipNumIndex * nYClipNum + (nYClipNumIndex > 0?1:0);
bmpaClipBmpArr[nBmpIndex] = new Bitmap(nClipWidth, nClipHight);
for(int nY = 0; nY < nClipHight; nY++)
{
for(int nX = 0; nX < nClipWidth; nX++)
{
int nClipX = nX + nClipWidth * nXClipNumIndex;
int nClipY = nY + nClipHight * nYClipNumIndex;
Color cClipPixel = bmpRes.GetPixel(nClipX, nClipY);
bmpaClipBmpArr[nBmpIndex].SetPixel(nX, nY, cClipPixel);
}
}
}
}
PictureBox[] picbShow = new PictureBox[nYClipNum * nXClipNum];
picbShow[0] = pictureBox1;
picbShow[1] = pictureBox2;
picbShow[2] = pictureBox3;
picbShow[3] = pictureBox4;
picbShow[4] = pictureBox5;
picbShow[5] = pictureBox6;
for (int nLoop = 0; nLoop < nYClipNum * nXClipNum; nLoop++)
{
picbShow[nLoop].Width = bmpRes.Width / nXClipNum;
picbShow[nLoop].Height = bmpRes.Height / nYClipNum;
picbShow[nLoop].Image = bmpaClipBmpArr[nLoop];
}
現(xiàn)在看看那些地方需要注意的了。其中
int nBmpIndex =
nXClipNumIndex + nYClipNumIndex * nYClipNum + (nYClipNumIndex > 0?1:0);
這句定義了存儲(chǔ)裁剪圖片對(duì)象在數(shù)組中的索引,需要注意的就是后面的(nYClipNumIndex > 0?1:0)——因?yàn)橹挥挟?dāng)裁剪的對(duì)象處于第一行以外的行時(shí)需要將索引加1;
另外,因?yàn)檫@種方法的效率不高,程序運(yùn)行起來(lái)還是頓了下。如果有興趣的話,可以將以上的代碼放到一個(gè)按鈕Click事件函數(shù)中,當(dāng)單擊該按鈕時(shí)就可以感覺(jué)到了。
方法二:運(yùn)用Clone函數(shù)局部復(fù)制。
同樣在Bitmap中可以找到Clone()方法,該方法有三個(gè)重載方法。Clone(),Clone(Rectangle, PixelFormat)和Clone(RectangleF, PixelFormat)。第一個(gè)方法將創(chuàng)建并返回一個(gè)精確的實(shí)例對(duì)象,后兩個(gè)就是我們這里需要用的局部裁剪了(其實(shí)后兩個(gè)方法本人覺(jué)得用法上差不多)。
將上面的程序稍稍改進(jìn)下——將裁剪的處理放到一個(gè)按鈕事件函數(shù)中,然后再托一個(gè)按鈕好窗體上,最后將下面的代碼復(fù)制到該按鈕的事件函數(shù)中。
for (int nYClipNumIndex = 0; nYClipNumIndex < nYClipNum; nYClipNumIndex++)
{
for (int nXClipNumIndex = 0; nXClipNumIndex < nXClipNum; nXClipNumIndex++)
{
int nClipWidth = bmpRes.Width / nXClipNum;
int nClipHight = bmpRes.Height / nYClipNum;
int nBmpIndex =
nXClipNumIndex + nYClipNumIndex * nYClipNum + (nYClipNumIndex > 0 ? 1 : 0);
Rectangle rClipRect = new Rectangle(nClipWidth * nXClipNumIndex,
nClipHight * nYClipNumIndex,
nClipWidth,
nClipHight);
bmpaClipBmpArr[nBmpIndex] = bmpRes.Clone(rClipRect, bmpRes.PixelFormat);
}
}
運(yùn)行程序,單擊按鈕檢驗(yàn)下,發(fā)現(xiàn)速度明顯快可很多。
其實(shí)這種方法較第一中方法不同的地方僅只是變換了for循環(huán)中的拷貝部分的處理,
Rectangle rClipRect = new Rectangle(nClipWidth * nXClipNumIndex,
nClipHight * nYClipNumIndex,
nClipWidth,
nClipHight);
bmpaClipBmpArr[nBmpIndex] = bmpRes.Clone(rClipRect, bmpRes.PixelFormat);
各種效果:
一. 底片效果
原理: GetPixel方法獲得每一點(diǎn)像素的值, 然后再使用SetPixel方法將取反后的顏色值設(shè)置到對(duì)應(yīng)的點(diǎn).
效果圖:
代碼實(shí)現(xiàn):
private void button1_Click(object sender, EventArgs e)
{
//以底片效果顯示圖像
try
{
int Height = this.pictureBox1.Image.Height;
int Width = this.pictureBox1.Image.Width;
Bitmap newbitmap = new Bitmap(Width, Height);
Bitmap oldbitmap = (Bitmap)this.pictureBox1.Image;
Color pixel;
for (int x = 1; x < Width; x++)
{
for (int y = 1; y < Height; y++)
{
int r, g, b;
pixel = oldbitmap.GetPixel(x, y);
r = 255 - pixel.R;
g = 255 - pixel.G;
b = 255 - pixel.B;
newbitmap.SetPixel(x, y, Color.FromArgb(r, g, b));
}
}
this.pictureBox1.Image = newbitmap;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
二. 浮雕效果
原理: 對(duì)圖像像素點(diǎn)的像素值分別與相鄰像素點(diǎn)的像素值相減后加上128, 然后將其作為新的像素點(diǎn)的值.
效果圖:
代碼實(shí)現(xiàn):
private void button1_Click(object sender, EventArgs e)
{
//以浮雕效果顯示圖像
try
{
int Height = this.pictureBox1.Image.Height;
int Width = this.pictureBox1.Image.Width;
Bitmap newBitmap = new Bitmap(Width, Height);
Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;
Color pixel1, pixel2;
for (int x = 0; x < Width - 1; x++)
{
for (int y = 0; y < Height - 1; y++)
{
int r = 0, g = 0, b = 0;
pixel1 = oldBitmap.GetPixel(x, y);
pixel2 = oldBitmap.GetPixel(x + 1, y + 1);
r = Math.Abs(pixel1.R - pixel2.R + 128);
g = Math.Abs(pixel1.G - pixel2.G + 128);
b = Math.Abs(pixel1.B - pixel2.B + 128);
if (r > 255)
r = 255;
if (r < 0)
r = 0;
if (g > 255)
g = 255;
if (g < 0)
g = 0;
if (b > 255)
b = 255;
if (b < 0)
b = 0;
newBitmap.SetPixel(x, y, Color.FromArgb(r, g, b));
}
}
this.pictureBox1.Image = newBitmap;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "信息提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
三. 黑白效果
原理: 彩色圖像處理成黑白效果通常有3種算法;
(1).最大值法: 使每個(gè)像素點(diǎn)的 R, G, B 值等于原像素點(diǎn)的 RGB (顏色值) 中最大的一個(gè);
(2).平均值法: 使用每個(gè)像素點(diǎn)的 R,G,B值等于原像素點(diǎn)的RGB值的平均值;
(3).加權(quán)平均值法: 對(duì)每個(gè)像素點(diǎn)的 R, G, B值進(jìn)行加權(quán)
---自認(rèn)為第三種方法做出來(lái)的黑白效果圖像最 "真實(shí)".
效果圖:
代碼實(shí)現(xiàn):
private void button1_Click(object sender, EventArgs e)
{
//以黑白效果顯示圖像
try
{
int Height = this.pictureBox1.Image.Height;
int Width = this.pictureBox1.Image.Width;
Bitmap newBitmap = new Bitmap(Width, Height);
Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;
Color pixel;
for (int x = 0; x < Width; x++)
for (int y = 0; y < Height; y++)
{
pixel = oldBitmap.GetPixel(x, y);
int r, g, b, Result = 0;
r = pixel.R;
g = pixel.G;
b = pixel.B;
//實(shí)例程序以加權(quán)平均值法產(chǎn)生黑白圖像
int iType =2;
switch (iType)
{
case 0://平均值法
Result = ((r + g + b) / 3);
break;
case 1://最大值法
Result = r > g ? r : g;
Result = Result > b ? Result : b;
break;
case 2://加權(quán)平均值法
Result = ((int)(0.7 * r) + (int)(0.2 * g) + (int)(0.1 * b));
break;
}
newBitmap.SetPixel(x, y, Color.FromArgb(Result, Result, Result));
}
this.pictureBox1.Image = newBitmap;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "信息提示");
}
}
四. 柔化效果
原理: 當(dāng)前像素點(diǎn)與周圍像素點(diǎn)的顏色差距較大時(shí)取其平均值.
效果圖:
代碼實(shí)現(xiàn):
private void button1_Click(object sender, EventArgs e)
{
//以柔化效果顯示圖像
try
{
int Height = this.pictureBox1.Image.Height;
int Width = this.pictureBox1.Image.Width;
Bitmap bitmap = new Bitmap(Width, Height);
Bitmap MyBitmap = (Bitmap)this.pictureBox1.Image;
Color pixel;
//高斯模板
int[] Gauss ={ 1, 2, 1, 2, 4, 2, 1, 2, 1 };
for (int x = 1; x < Width - 1; x++)
for (int y = 1; y < Height - 1; y++)
{
int r = 0, g = 0, b = 0;
int Index = 0;
for (int col = -1; col <= 1; col++)
for (int row = -1; row <= 1; row++)
{
pixel = MyBitmap.GetPixel(x + row, y + col);
r += pixel.R * Gauss[Index];
g += pixel.G * Gauss[Index];
b += pixel.B * Gauss[Index];
Index++;
}
r /= 16;
g /= 16;
b /= 16;
//處理顏色值溢出
r = r > 255 ? 255 : r;
r = r < 0 ? 0 : r;
g = g > 255 ? 255 : g;
g = g < 0 ? 0 : g;
b = b > 255 ? 255 : b;
b = b < 0 ? 0 : b;
bitmap.SetPixel(x - 1, y - 1, Color.FromArgb(r, g, b));
}
this.pictureBox1.Image = bitmap;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "信息提示");
}
}
五.銳化效果
原理:突出顯示顏色值大(即形成形體邊緣)的像素點(diǎn).
效果圖:
實(shí)現(xiàn)代碼:
private void button1_Click(object sender, EventArgs e)
{
//以銳化效果顯示圖像
try
{
int Height = this.pictureBox1.Image.Height;
int Width = this.pictureBox1.Image.Width;
Bitmap newBitmap = new Bitmap(Width, Height);
Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;
Color pixel;
//拉普拉斯模板
int[] Laplacian ={ -1, -1, -1, -1, 9, -1, -1, -1, -1 };
for (int x = 1; x < Width - 1; x++)
for (int y = 1; y < Height - 1; y++)
{
int r = 0, g = 0, b = 0;
int Index = 0;
for (int col = -1; col <= 1; col++)
for (int row = -1; row <= 1; row++)
{
pixel = oldBitmap.GetPixel(x + row, y + col); r += pixel.R * Laplacian[Index];
g += pixel.G * Laplacian[Index];
b += pixel.B * Laplacian[Index];
Index++;
}
//處理顏色值溢出
r = r > 255 ? 255 : r;
r = r < 0 ? 0 : r;
g = g > 255 ? 255 : g;
g = g < 0 ? 0 : g;
b = b > 255 ? 255 : b;
b = b < 0 ? 0 : b;
newBitmap.SetPixel(x - 1, y - 1, Color.FromArgb(r, g, b));
}
this.pictureBox1.Image = newBitmap;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "信息提示");
}
}
六. 霧化效果
原理: 在圖像中引入一定的隨機(jī)值, 打亂圖像中的像素值
效果圖:
實(shí)現(xiàn)代碼:
private void button1_Click(object sender, EventArgs e)
{
//以霧化效果顯示圖像
try
{
int Height = this.pictureBox1.Image.Height;
int Width = this.pictureBox1.Image.Width;
Bitmap newBitmap = new Bitmap(Width, Height);
Bitmap oldBitmap = (Bitmap)this.pictureBox1.Image;
Color pixel;
for (int x = 1; x < Width - 1; x++)
for (int y = 1; y < Height - 1; y++)
{
System.Random MyRandom = new Random();
int k = MyRandom.Next(123456);
//像素塊大小
int dx = x + k % 19;
int dy = y + k % 19;
if (dx >= Width)
dx = Width - 1;
if (dy >= Height)
dy = Height - 1;
pixel = oldBitmap.GetPixel(dx, dy);
newBitmap.SetPixel(x, y, pixel);
}
this.pictureBox1.Image = newBitmap;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "信息提示");
}
}