亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

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

2020-01-24 01:11:56
字體:
來源:轉載
供稿:網友

這里之所以說“淺談”是因為我這里只是簡單的介紹如何使用Visual C#進行圖像的讀入、保存以及對像素的訪問。而不涉及太多的算法。

一、讀取圖像

在Visual C#中我們可以使用一個Picture Box控件來顯示圖片,如下:

復制代碼 代碼如下:

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("加載圖片失敗!", "錯誤");
            return;
        }
        pbxShowImage.Image = bmp;
        ofd.Dispose();
    }
}

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

二、保存圖像

復制代碼 代碼如下:

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();
    }
}

三、對像素的訪問

我們可以來建立一個GrayBitmapData類來做相關的處理。整個類的程序如下:

復制代碼 代碼如下:

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彩色圖轉換為灰度圖
                        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];
                }
            }
        }
//獲得一個向量的中值
        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類中,只要我們對一個二維數組Data進行一系列的操作就是對圖片的操作處理。在窗口上,我們可以使用
一個按鈕來做各種調用:

復制代碼 代碼如下:

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

四、總結

在Visual c#中對圖像進行處理或訪問,需要先建立一個Bitmap對象,然后通過其LockBits方法來獲得一個BitmapData類的對象,然后通過獲得其像素數據的首地址來對Bitmap對象的像素數據進行操作。當然,一種簡單但是速度慢的方法是用Bitmap類的GetPixel和SetPixel方法。其中BitmapData類的Stride屬性為每行像素所占的字節。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
最好看的2019年中文视频| 国产亚洲免费的视频看| 日韩精品视频中文在线观看| 亚洲人av在线影院| www.亚洲免费视频| 亚洲综合一区二区不卡| 一本大道香蕉久在线播放29| 亚洲变态欧美另类捆绑| 日韩成人久久久| 国产精品户外野外| 国产精品午夜国产小视频| 91精品国产免费久久久久久| 亚洲大尺度美女在线| 欧洲精品在线视频| 亚洲三级av在线| 亚洲精品欧美一区二区三区| 国产一区私人高清影院| 久久中文字幕视频| 97国产在线视频| 亚洲图中文字幕| 国产精品久久久久久久久久99| 91精品国产高清久久久久久久久| 日本欧美中文字幕| 国外视频精品毛片| 国产精品自产拍高潮在线观看| 91国产美女视频| 精品国产乱码久久久久久婷婷| 国产视频亚洲精品| 97成人精品区在线播放| 精品一区二区三区电影| 97在线观看免费高清| 亚洲成人黄色网址| 国内伊人久久久久久网站视频| 精品国产91久久久| 国产一区二区三区视频在线观看| 日韩免费电影在线观看| 97免费中文视频在线观看| 福利二区91精品bt7086| 91精品国产91久久久| 欧美日韩视频免费播放| 日韩在线观看精品| 日韩精品免费在线观看| 动漫精品一区二区| 茄子视频成人在线| 久久精品国产久精国产思思| 中文字幕欧美国内| 日韩欧美国产黄色| 欧美成人精品在线| 精品国内产的精品视频在线观看| 韩国一区二区电影| 欧美国产欧美亚洲国产日韩mv天天看完整| 91精品国产高清久久久久久久久| 九九久久久久久久久激情| 5252色成人免费视频| 91影院在线免费观看视频| 亚洲影院污污.| 国产一区二区丝袜高跟鞋图片| 欧美日韩激情网| 色久欧美在线视频观看| 亚洲天堂男人天堂女人天堂| 日韩欧美在线中文字幕| 亚洲欧美国产制服动漫| 国产热re99久久6国产精品| 国产精品久久久久久久久久三级| 美日韩精品免费观看视频| 欧美www视频在线观看| 欧美成人精品不卡视频在线观看| 亚洲一区二区三区毛片| 成人黄色av网站| 国产成人极品视频| 国产女人18毛片水18精品| 国产精品中文久久久久久久| 欧美怡春院一区二区三区| 国产欧美日韩精品丝袜高跟鞋| 亚洲欧洲在线播放| 91av视频导航| 日韩美女写真福利在线观看| 成人激情视频在线观看| 伊人成人开心激情综合网| 国产成人亚洲综合| 色悠悠久久88| 久久久影视精品| 日韩av电影在线播放| 爱福利视频一区| 日韩在线视频播放| 国内精品模特av私拍在线观看| 亚洲国产另类 国产精品国产免费| 国产91免费看片| 亚洲精品国产免费| 亚洲人成在线观看网站高清| 亚洲人成人99网站| 国产精品成人免费电影| 在线不卡国产精品| 亚洲国产精彩中文乱码av| 国产欧美一区二区三区在线| 日韩av在线导航| 成人亚洲欧美一区二区三区| 麻豆一区二区在线观看| 欧美视频在线观看 亚洲欧| 日本不卡免费高清视频| 亚洲国产精品成人va在线观看| 亚洲a一级视频| 久久99亚洲精品| 亚洲午夜av电影| 国产人妖伪娘一区91| 狠狠色狠狠色综合日日小说| 亚洲一区二区久久久久久| 日韩中文字幕国产| 成人激情电影一区二区| 日韩大片免费观看视频播放| 国产精品美女999| 精品国产一区av| 97久久久久久| 国产成人涩涩涩视频在线观看| 伊人久久久久久久久久久久久| 欧美午夜丰满在线18影院| 亚洲一区二区三区乱码aⅴ| 国语自产精品视频在免费| 欧美成人精品xxx| 亚洲精品国产电影| 亚洲天堂免费观看| 91精品久久久久久久久中文字幕| 欧美日韩中文在线观看| 日韩av电影手机在线观看| 亚洲视频axxx| 97久久精品人人澡人人爽缅北| 国产精品视频1区| 日韩最新免费不卡| 久久综合色影院| 精品人伦一区二区三区蜜桃免费| 亚洲精品久久久久久久久久久久| 国产一区二区三区在线观看网站| 久久91精品国产91久久久| 亚洲第一二三四五区| 欧美日韩精品在线播放| 亚洲精品日韩丝袜精品| 亚洲在线免费观看| 国产视频精品在线| 国产精品福利无圣光在线一区| 久久九九有精品国产23| 国产精品成熟老女人| 久久九九精品99国产精品| 久久精品视频中文字幕| 久久成人精品电影| 国产在线拍揄自揄视频不卡99| 国产午夜精品美女视频明星a级| 91精品视频免费| 日韩动漫免费观看电视剧高清| 国产欧美日韩精品丝袜高跟鞋| 久久亚洲欧美日韩精品专区| 国产成人精品视频在线| 97视频色精品| 国产一区二区黑人欧美xxxx| 亚洲欧洲国产一区| 97视频在线观看视频免费视频| 性色av一区二区三区在线观看| 欧美精品电影免费在线观看| 性欧美xxxx交| 欧美日韩国产一区在线| 亚洲欧洲中文天堂| 亚洲全黄一级网站| 国产成人a亚洲精品| 中文.日本.精品| 国产精品三级美女白浆呻吟|