1. 程式人生 > 其它 >C# 圖片處理詳解

C# 圖片處理詳解

技術標籤:圖片分析c#圖片分析灰度

本文主要介紹:獲取圖片的灰度/修改彩色圖片為黑白圖片/修改圖片的對比度

Bitmap類:Bitmap物件封裝了一個GDI+的點陣圖,此點陣圖由圖形影象的畫素,以及其屬性組成。用於處理由畫素資料定義的影象的物件,包括如下屬性和方法

1.GetPixel方法和SetPixel方法:用於獲取和設定影象的指定畫素的顏色

2.PixelFormat屬性:返回影象的畫素格式

3.Palette屬性:獲取和設定影象所使用的顏色調色盤

4.Height/Width屬性:返回影象的高度和寬度

5.LockBits方法和UnlockBits是一個很好的方法這種方法可以使我們指定畫素的範圍來控制點陣圖的任一部分,從而比美女對點陣圖的畫素逐個進行處理,每呼叫一次LockBits都要呼叫UnlockBits進行解鎖

BitmapData類:

1.Height/Width屬性:被鎖定點陣圖的高度/寬度屬性

2.PixelsFormat屬性:資料實際畫素格式

3.Scan0屬性:被鎖定陣列的首位元組地址,如果整個影象被鎖定,則是影象的第一個位元組地址

4.Stride屬性:步幅,也稱為掃描寬度

private string path=Application.StartupPath;
private byte[] mappdata;

private void button1_Click(object sender,EventArgs e)
{
    Image img=null;
    Bitmap map=null;
    //讀取對應圖片
    using(FileStream fs=new FileStream(path+"\\1.png",FileMode.Open))
    {
        img=Image.FromStream(fs);
    }
    map=(Bitmap)img;
    //將圖片轉換為黑白圖片
    ChangeToGrayImg(map);
    //GetImageGrayData(map);
    //Bitmap map1=ChangeImageGrayOnPixel(map,10);
    //Bitmap map2=ChangeImageGrayOnMemory(map,100);
    //Bitmap map3=ChangeImageGrayOnPixel(map,10);
}
//修改圖片為黑白的三種演算法
private void ChangeToGrayImg(Bitmap map)
{
    int w=map.Width;
    int h=map.Height;
    Color pixel;
    for(int x=0;x<w;x++)
    {
        for(int y=0;y<h;y++)
        {
            pixel=map.GetPixel(x,y);
            int r=pixel.R;
            int g=pixel.G;
            int b=pixel.B;
            int result=0;
            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://加權平均值法
                    result=((int)(0.7*r)+(int)(0.2*g)+(int)(0.1*b));
                    break;
            }
        map.SetPixel(x,y,Color.FromArgb(result,result,result));
        }
    }
    //轉換完成之後儲存圖片,這裡沒有重構,下面幾個方法也能用
    MemoryStream ms=new MemoryStream();
    map.Save(ms,ImageFormat.Bmp);
    ms.Seek(0,SeekOrigin.Begin);
    byte[] buffer=new byte[ms.Length];
    ms.Read(buffer,0,buffer.Length);
    ms.Dispose();
    using(FileStream fs=new FileStream(path+"\\111.bmp",FileMode.CreateNew,FileAccess.Write))
    {
        fs.Write(buffer,0,buffer.Length);
    }
}
//根據圖片獲得圖片的灰度陣列
private void GetImageGrayData(Bitmap map)
{
    BitmapData bmpData=map.LockBits(new Rectangle(0,0,map.Width,map.Height),ImageLockMode.ReadOnly,PixelFormat.Format8bppIndexed);
    //獲取掃描線的寬度
    int stride=bmpData.Stride;
    //顯示寬度與掃描線寬度的間隙
    int offset=stride-map.Width;
    //獲取bmpData的記憶體起始位置
    IntPtr iptr=bmpData.Scan0;
    //用stride寬度,表示這是記憶體區域的大小
    int scanBytes=stride*map.Height;
    //為目標分配記憶體
    mapdata=new byte[scanBytes];
    //copy記憶體中的資料到目標陣列中
    System.Runtime.InteropServices.Marshal.Copy(iptr,mapdata,0,scanBytes);
}
//基於畫素和基於記憶體修改圖片的對比度
//1.基於畫素修改圖片的對比度
public Bitmap ChangeImageGrayOnPixel(Bitmap bitmap,int degree/*對比度的加深比例*/)
{
    Color curColor;
    int grayR,grayG,grayB;
    double Deg=(100.0+degree)/100.0;
    for(int i=0;i<bitmap.Width;i++)
    {
        for(int j=0;j<bitmap.Height;j++)
        {
            curColor=bitmap.GetPixel(i,j);    
            grayR=Convert.ToInt16((((curColor.R/255.0-0.5)*Deg+0.5))*255);
            grayG=Convert.ToInt16((((curColor.G/255.0-0.5)*Deg+0.5))*255);
            grayB=Convert.ToInt16((((curColor.B/255.0-0.5)*Deg+0.5))*255);
            if(grayR<0)
                grayR=0;
            else if(grayR>255)
                grayR=255;
            if(grayG<0)
                grayG=0;
            else if(grayG>255)
                grayG=255;
            if(grayB<0)
                grayB=0;
            else if(grayB>255)
                grayB=255;
            bitmap.SetPixel(i,j,Color.FromArgb(grayR,grayG,grayB));
        }
    }
    return bitmap;
}
 
//2.基於記憶體修改圖片的對比度
public unsafe Bitmap ChangeImageGrayOnMemory(Bitmap bitmap,int degree)
{
    if(bitmap==null)
    {
       return null; 
    }
    double Deg=(100+degree)/100.0;
    int width=bitmap.Width;
    int height=bitmap.Height;
    int length=height*3*width;
    byte[] RGB=new byte[length];
    BitmapData data=bitmap.LockBits(new Rectangle(0,0,width,height),ImageLockMode.ReadWrite,PixelFormat.Format24bppRgb);
    IntPtr Scan0=data.Scan0;
    System.Runtime.InteropServices.Marshal.Copy(Scan0,RGB,0,length);
    double gray=0;
    for(int i=0;i<RGB.Length;i+=3)
    {
        for(int j=0;j<3;j++)
        {
            gray=(((RGB[i+j]/255.0-0.5)*Deg+0.5))*255.0;
            if(gray>255)
            {
                gray=255;
            }
            else if(gray<0)
            {
                gray=0;
            }
            RGB[i+j]=(byte)gray;
        }
    }
    System.Runtime.InteropServices.Marshal.Copy(RGB,0,Scan0,length);
    bitmap.UnlockBits(data);
    return bitmap;
}