欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談Visual C#進(jìn)行圖像處理(讀取、保存以及對(duì)像素的訪問(wèn))

 更新時(shí)間:2016年04月18日 10:04:21   作者:彭軍  
本文主要介紹利用C#對(duì)圖像進(jìn)行讀取、保存以及對(duì)像素的訪問(wèn)等操作,介紹的比較簡(jiǎn)單,希望對(duì)初學(xué)者有所幫助。

這里之所以說(shuō)“淺談”是因?yàn)槲疫@里只是簡(jiǎn)單的介紹如何使用Visual C#進(jìn)行圖像的讀入、保存以及對(duì)像素的訪問(wèn)。而不涉及太多的算法。

一、讀取圖像

在Visual C#中我們可以使用一個(gè)Picture Box控件來(lái)顯示圖片,如下:

復(fù)制代碼 代碼如下:

private void btnOpenImage_Click(object sender, EventArgs e)
{
    OpenFileDialog ofd = new OpenFileDialog();
    ofd.Filter = "BMP Files(*.bmp)|*.bmp|JPG Files(*.jpg;*.jpeg)|*.jpg;*.jpeg|All Files(*.*)|*.*";
    ofd.CheckFileExists = true;
    ofd.CheckPathExists = true;
    if (ofd.ShowDialog() == DialogResult.OK)
    {
        //pbxShowImage.ImageLocation = ofd.FileName;
        bmp = new Bitmap(ofd.FileName);
        if (bmp==null)
        {
            MessageBox.Show("加載圖片失敗!", "錯(cuò)誤");
            return;
        }
        pbxShowImage.Image = bmp;
        ofd.Dispose();
    }
}

其中bmp為類的一個(gè)對(duì)象:private Bitmap bmp=null;
在使用Bitmap類和BitmapData類之前,需要使用using System.Drawing.Imaging;

二、保存圖像

復(fù)制代碼 代碼如下:

private void btnSaveImage_Click(object sender, EventArgs e)
{
    if (bmp == null) return;
    SaveFileDialog sfd = new SaveFileDialog();
    sfd.Filter = "BMP Files(*.bmp)|*.bmp|JPG Files(*.jpg;*.jpeg)|*.jpg;*.jpeg|All Files(*.*)|*.*";
    if (sfd.ShowDialog() == DialogResult.OK)
    {
        pbxShowImage.Image.Save(sfd.FileName);
        MessageBox.Show("保存成功!","提示");
        sfd.Dispose();
    }
}

三、對(duì)像素的訪問(wèn)

我們可以來(lái)建立一個(gè)GrayBitmapData類來(lái)做相關(guān)的處理。整個(gè)類的程序如下:

復(fù)制代碼 代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
namespace ImageElf
{
    class GrayBitmapData
    {
        public byte[,] Data;//保存像素矩陣
        public int Width;//圖像的寬度
        public int Height;//圖像的高度
        public GrayBitmapData()
        {
            this.Width = 0;
            this.Height = 0;
            this.Data = null;
        }
        public GrayBitmapData(Bitmap bmp)
        {
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            this.Width = bmpData.Width;
            this.Height = bmpData.Height;
            Data = new byte[Height, Width];
            unsafe
            {
                byte* ptr = (byte*)bmpData.Scan0.ToPointer();
                for (int i = 0; i < Height; i++)
                {
                    for (int j = 0; j < Width; j++)
                    {
    //將24位的RGB彩色圖轉(zhuǎn)換為灰度圖
                        int temp = (int)(0.114 * (*ptr++)) + (int)(0.587 * (*ptr++))+(int)(0.299 * (*ptr++));
                        Data[i, j] = (byte)temp;
                    }
                    ptr += bmpData.Stride - Width * 3;//指針加上填充的空白空間
                }
            }
            bmp.UnlockBits(bmpData);
        }
        public GrayBitmapData(string path)
            : this(new Bitmap(path))
        {
        }
        public Bitmap ToBitmap()
        {
            Bitmap bmp=new Bitmap(Width,Height,PixelFormat.Format24bppRgb);
            BitmapData bmpData=bmp.LockBits(new Rectangle(0,0,Width,Height),ImageLockMode.WriteOnly,PixelFormat.Format24bppRgb);
            unsafe
            {
                byte* ptr=(byte*)bmpData.Scan0.ToPointer();
                for(int i=0;i<Height;i++)
                {
                    for(int j=0;j<Width;j++)
                    {
                        *(ptr++)=Data[i,j];
                        *(ptr++)=Data[i,j];
                        *(ptr++)=Data[i,j];
                    }
                    ptr+=bmpData.Stride-Width*3;
                }
            }
            bmp.UnlockBits(bmpData);
            return bmp;
        }
        public void ShowImage(PictureBox pbx)
        {
            Bitmap b = this.ToBitmap();
            pbx.Image = b;
            //b.Dispose();
        }
        public void SaveImage(string path)
        {
            Bitmap b=ToBitmap();
            b.Save(path);
            //b.Dispose();
        }
//均值濾波
        public void AverageFilter(int windowSize)
        {
            if (windowSize % 2 == 0)
            {
                return;
            }
            for (int i = 0; i < Height; i++)
            {
                for (int j = 0; j < Width; j++)
                {
                    int sum = 0;
                    for (int g = -(windowSize - 1) / 2; g <= (windowSize - 1) / 2; g++)
                    {
                        for (int k = -(windowSize - 1) / 2; k <= (windowSize - 1) / 2; k++)
                        {
                            int a = i + g, b = j + k;
                            if (a < 0) a = 0;
                            if (a > Height - 1) a = Height - 1;
                            if (b < 0) b = 0;
                            if (b > Width - 1) b = Width - 1;
                            sum += Data[a, b];
                        }
                    }
                    Data[i,j]=(byte)(sum/(windowSize*windowSize));
                }
            }
        }
//中值濾波
        public void MidFilter(int windowSize)
        {
            if (windowSize % 2 == 0)
            {
                return;
            }
            int[] temp = new int[windowSize * windowSize];
            byte[,] newdata = new byte[Height, Width];
            for (int i = 0; i < Height; i++)
            {
                for (int j = 0; j < Width; j++)
                {
                    int n = 0;
                    for (int g = -(windowSize - 1) / 2; g <= (windowSize - 1) / 2; g++)
                    {
                        for (int k = -(windowSize - 1) / 2; k <= (windowSize - 1) / 2; k++)
                        {
                            int a = i + g, b = j + k;
                            if (a < 0) a = 0;
                            if (a > Height - 1) a = Height - 1;
                            if (b < 0) b = 0;
                            if (b > Width - 1) b = Width - 1;
                            temp[n++]= Data[a, b];
                        }
                    }
                    newdata[i, j] = GetMidValue(temp,windowSize*windowSize);
                }
            }
            for (int i = 0; i < Height; i++)
            {
                for (int j = 0; j < Width; j++)
                {
                    Data[i, j] = newdata[i, j];
                }
            }
        }
//獲得一個(gè)向量的中值
        private byte GetMidValue(int[] t, int length)
        {
            int temp = 0;
            for (int i = 0; i < length - 2; i++)
            {
                for (int j = i + 1; j < length - 1; j++)
                {
                    if (t[i] > t[j])
                    {
                        temp = t[i];
                        t[i] = t[j];
                        t[j] = temp;
                    }
                }
            }
            return (byte)t[(length - 1) / 2];
        }
//一種新的濾波方法,是亮的更亮、暗的更暗
        public void NewFilter(int windowSize)
        {
            if (windowSize % 2 == 0)
            {
                return;
            }
            for (int i = 0; i < Height; i++)
            {
                for (int j = 0; j < Width; j++)
                {
                    int sum = 0;
                    for (int g = -(windowSize - 1) / 2; g <= (windowSize - 1) / 2; g++)
                    {
                        for (int k = -(windowSize - 1) / 2; k <= (windowSize - 1) / 2; k++)
                        {
                            int a = i + g, b = j + k;
                            if (a < 0) a = 0;
                            if (a > Height - 1) a = Height - 1;
                            if (b < 0) b = 0;
                            if (b > Width - 1) b = Width - 1;
                            sum += Data[a, b];
                        }
                    }
                    double avg = (sum+0.0) / (windowSize * windowSize);
                    if (avg / 255 < 0.5)
                    {
                        Data[i, j] = (byte)(2 * avg / 255 * Data[i, j]);
                    }
                    else
                    {
                        Data[i,j]=(byte)((1-2*(1-avg/255.0)*(1-Data[i,j]/255.0))*255);
                    }
                }
            }
        }
//直方圖均衡
        public void HistEqual()
        {
            double[] num = new double[256] ;
            for(int i=0;i<256;i++) num[i]=0;
            for (int i = 0; i < Height; i++)
            {
                for (int j = 0; j < Width; j++)
                {
                    num[Data[i, j]]++;
                }
            }
            double[] newGray = new double[256];
            double n = 0;
            for (int i = 0; i < 256; i++)
            {
                n += num[i];
                newGray[i] = n * 255 / (Height * Width);
            }
            for (int i = 0; i < Height; i++)
            {
                for (int j = 0; j < Width; j++)
                {
                    Data[i,j]=(byte)newGray[Data[i,j]];
                }
            }
        }
}
}

在GrayBitmapData類中,只要我們對(duì)一個(gè)二維數(shù)組Data進(jìn)行一系列的操作就是對(duì)圖片的操作處理。在窗口上,我們可以使用
一個(gè)按鈕來(lái)做各種調(diào)用:

復(fù)制代碼 代碼如下:

//均值濾波
private void btnAvgFilter_Click(object sender, EventArgs e)
{
    if (bmp == null) return;
    GrayBitmapData gbmp = new GrayBitmapData(bmp);
    gbmp.AverageFilter(3);
    gbmp.ShowImage(pbxShowImage);
}
//轉(zhuǎn)換為灰度圖
private void btnToGray_Click(object sender, EventArgs e)
{
    if (bmp == null) return;
    GrayBitmapData gbmp = new GrayBitmapData(bmp);
    gbmp.ShowImage(pbxShowImage);
}

四、總結(jié)

在Visual c#中對(duì)圖像進(jìn)行處理或訪問(wèn),需要先建立一個(gè)Bitmap對(duì)象,然后通過(guò)其LockBits方法來(lái)獲得一個(gè)BitmapData類的對(duì)象,然后通過(guò)獲得其像素?cái)?shù)據(jù)的首地址來(lái)對(duì)Bitmap對(duì)象的像素?cái)?shù)據(jù)進(jìn)行操作。當(dāng)然,一種簡(jiǎn)單但是速度慢的方法是用Bitmap類的GetPixel和SetPixel方法。其中BitmapData類的Stride屬性為每行像素所占的字節(jié)。

相關(guān)文章

  • C#中靜態(tài)構(gòu)造函數(shù)的幾點(diǎn)說(shuō)明介紹

    C#中靜態(tài)構(gòu)造函數(shù)的幾點(diǎn)說(shuō)明介紹

    本篇文章主要是對(duì)C#中靜態(tài)構(gòu)造函數(shù)的幾點(diǎn)說(shuō)明進(jìn)行了介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2014-01-01
  • FTPClientHelper輔助類 實(shí)現(xiàn)文件上傳,目錄操作,下載等操作

    FTPClientHelper輔助類 實(shí)現(xiàn)文件上傳,目錄操作,下載等操作

    這篇文章主要分享了一個(gè)FTPClientHelper輔助類和介紹了常用的FTP命令,需要的朋友可以參考下。
    2016-06-06
  • 圖文介紹c#封裝方法

    圖文介紹c#封裝方法

    在本篇內(nèi)容里小編給大家分享的是關(guān)于c#使用封裝方法以及相關(guān)知識(shí)點(diǎn),對(duì)此有需要的朋友們可以學(xué)習(xí)下。
    2018-12-12
  • C# Web應(yīng)用調(diào)試開(kāi)啟外部訪問(wèn)步驟解析

    C# Web應(yīng)用調(diào)試開(kāi)啟外部訪問(wèn)步驟解析

    本文主要介紹了C# Web應(yīng)用調(diào)試開(kāi)啟外部訪問(wèn)的實(shí)現(xiàn)過(guò)程與方法。具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-01-01
  • C#向Word插入排版精良的TextBox

    C#向Word插入排版精良的TextBox

    這篇文章主要為大家詳細(xì)介紹了C#向Word插入排版精良的Text Box的相關(guān)方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 詳解C#面相對(duì)象編程中的繼承特性

    詳解C#面相對(duì)象編程中的繼承特性

    這篇文章主要介紹了C#面相對(duì)象編程中的繼承特性,是C#入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2016-01-01
  • C#實(shí)現(xiàn)將javascript文件編譯成dll文件的方法

    C#實(shí)現(xiàn)將javascript文件編譯成dll文件的方法

    這篇文章主要介紹了C#實(shí)現(xiàn)將javascript文件編譯成dll文件的方法,涉及C#編譯生成dll動(dòng)態(tài)鏈接庫(kù)文件的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-11-11
  • 解決Unity urp級(jí)聯(lián)陰影接縫問(wèn)題

    解決Unity urp級(jí)聯(lián)陰影接縫問(wèn)題

    通過(guò)從unity內(nèi)部函數(shù)中抽幾個(gè)出來(lái)改造,強(qiáng)制取某個(gè)裁切球的級(jí)聯(lián)陰影映射,通過(guò)案例給大家詳細(xì)介紹,文中給出了完整的urp shader代碼,對(duì)Unity級(jí)聯(lián)陰影知識(shí)感興趣的朋友一起看看吧
    2021-06-06
  • 在C#項(xiàng)目中如何使用NHibernate詳解

    在C#項(xiàng)目中如何使用NHibernate詳解

    NHibernate的設(shè)計(jì)思想和Hibernate的設(shè)計(jì)思想基本相同,都是為了避免頻繁的編寫sql腳本,使用面向?qū)ο蟮姆绞绞褂胔ql語(yǔ)句進(jìn)行查詢。下面這篇文章主要給大家介紹了關(guān)于在C#項(xiàng)目中如何使用NHibernate的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-04-04
  • Unity Shader實(shí)現(xiàn)描邊OutLine效果

    Unity Shader實(shí)現(xiàn)描邊OutLine效果

    這篇文章主要為大家詳細(xì)介紹了Unity Shader實(shí)現(xiàn)描邊OutLine效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-01-01

最新評(píng)論