1. 程式人生 > >使用C語言操作bitmap(彩色變灰色,黑白)

使用C語言操作bitmap(彩色變灰色,黑白)

這裡有有一篇bitmap基本格式的部落格,不再贅述
https://www.cnblogs.com/ZXNblog/p/4046342.html
下面講述怎麼將24為的bitmap影象變成灰色和黑白。

  1. 定義BITMAPFILEHEADER,和BITMAPINFOHEADER,並從原影象獲取影象資訊

        typedef unsigned char uc;
        BITMAPFILEHEADER fileHeader;//在windows.h檔案中有定義 
        BITMAPINFOHEADER infoHeader;//同上 
    
        FILE* f=fopen("1.bmp","rb");
        FILE* f2=fopen("4.bmp","wb");
        fread(&fileHeader,sizeof(BITMAPFILEHEADER),1,f);
        fread(&infoHeader,sizeof(BITMAPINFOHEADER),1,f);
        int height,width;
        width=infoHeader.biWidth;
        height=infoHeader.biHeight;
        uc* r=(uc*)malloc(width*height);//紅色矩陣 
        uc* g=(uc*)malloc(width*height);//綠色矩陣 
        uc* b=(uc*)malloc(width*height);//藍色矩陣 
    
  2. 將影象每個畫素的rgb顏色讀取到陣列中

    void loadImage(FILE* fin,uc* r,uc* g,uc *b,int height,int width){
        //fin檔案指標已經過了兩個檔案頭 
        int stride=((24*width+31)>>5)<<2;//取4的倍數,
        uc *t=(uc*)malloc(stride);; 
        for(int i=0;i<height;i++){
            fread(t,1,stride,fin);
            for(int j=0;j<width;j++){
                *(r+i*width+j)=t[3*j+2];//紅色,從左下角開始讀取 
                *(g+i*width+j)=t[3*j+1];//綠色 
                *(b+i*width+j)=t[3*j];//藍色 
            }
        }
        free(t);
        t=NULL;
    }
    
  3. 定義寫入檔案的函式

    void removeBitmapColor(FILE* fout,int height,int width,uc (*fun)(uc r,uc g,uc b),uc *r,uc *g,uc *b){
        //fun為計算灰度的函式指標
        int stride=((24*width+31)>>5)<<2;
        uc *t=(uc*)malloc(stride);
        uc temp;
        for(int i=0;i<height;i++){
            for(int j=0;j<width;j++){
                temp=(*fun)(*(r+i*width+j),*(g+i*width+j),*(b+i*width+j));
    //          printf("%d ",temp);
    /*恢復原圖 
                t[3*j]=*(b+i*width+j);
                t[3*j+1]=*(g+i*width+j);
                t[3*j+2]=*(r+i*width+j);
    */  
    /*影象去色,變成灰度影象
                t[3*j]=t[3*j+1]=t[3*j+2]=temp;  */
    /*變成黑白影象 
            if(temp>128)
                t[3*j]=t[3*j+1]=t[3*j+2]=(uc)255;
            else
                t[3*j]=t[3*j+1]=t[3*j+2]=0;
            }
            fwrite(t,1,stride,fout);*/
        }
    }   
    
  4. 定義灰度定義函式

    uc func1(uc r,uc b,uc g){//matlab去色演算法 
        float f=0.2989*(int)r+0.587*(int)b+0.114*(int)g;
        return uc((int)f);
    }
    uc func2(uc r,uc b,uc g){//opencv去色演算法 
        float f=0.299*(int)r+0.587*(int)b+0.114*(int)g;
    }
    
  5. 主函式呼叫,並釋放指標

    ILE* f2=fopen("4.bmp","wb");
    fwrite(&fileHeader,sizeof(BITMAPFILEHEADER),1,f2);
    fwrite(&infoHeader,sizeof(BITMAPINFOHEADER),1,f2);
    loadImage(f,r,g,b,height,width);    
    removeBitmapColor(f2,height,width,&func1,r,g,b);
    fclose(f);
    free(r);
    free(g);
    free(b);
    r=NULL;
    g=NULL;
    b=NULL;
    

    原圖:
    24位
    灰色影象:
    24位
    黑白影象:
    24位