西西軟件園多重安全檢測下載網(wǎng)站、值得信賴的軟件下載站!
西西首頁 電腦軟件 安卓軟件 電腦游戲 安卓游戲 排行榜 專題合集

24位bmp位圖轉(zhuǎn)灰度圖

免費版帶源碼
  • 24位bmp位圖轉(zhuǎn)灰度圖免費版帶源碼
  • 軟件大小:2.6M
  • 更新時間:2015-05-27 17:39
  • 軟件語言:中文
  • 軟件廠商:
  • 軟件類別:國產(chǎn)軟件 / 免費軟件 / 編程輔助
  • 軟件等級:4級
  • 應(yīng)用平臺:WinAll, WinXP, Win7
  • 官方網(wǎng)站:http://www.innovatechautomation.com
  • 應(yīng)用備案:
好評:50%
壞評:50%

軟件介紹

實現(xiàn)位圖的讀取顯示保存,能完成24位位圖的轉(zhuǎn)換,是一個典型的圖像處理基礎(chǔ)程序,程序很好,很簡單清晰,容易看懂,但是所有圖像信息頭和數(shù)據(jù)的處理全在響應(yīng)函數(shù)和ondrow函數(shù)里!

將24位真彩色圖轉(zhuǎn)換為灰度圖

在圖像處理中,我們經(jīng)常需要將真彩色圖像轉(zhuǎn)換為黑白圖像。嚴(yán)格的講應(yīng)該是灰度圖,因為真正的黑白圖像是二色,即只有純黑,純白二色。開始之前,我們先簡單補(bǔ)充一下計算機(jī)中圖像的表示原理。

計算機(jī)中的圖像大致可以分成兩類:位圖(Bitmap)和矢量圖(Metafile)。 位圖可以視為一個二維的網(wǎng)格,整個圖像就是由很多個點組成的,點的個數(shù)等于位圖的寬乘以高。每個點被稱為一個像素點,每個像素點有確定的顏色,當(dāng)很多個像素合在一起時就形成了一幅完整的圖像。

我們通常使用的圖像大部分都是位圖,如數(shù)碼相機(jī)拍攝的照片,都是位圖。因為位圖可以完美的表示圖像的細(xì)節(jié),能較好的 還原圖像的原景。

但位圖也有缺點:第一是體積比較大,所以人們開發(fā)了很多壓縮圖像格式來儲存位圖圖像,目前應(yīng)用最廣的是JPEG格式,在WEB上得到了廣泛應(yīng)用,另外還有GIF,PNG等 等。第二是位圖在放大時,不可避免的會出現(xiàn)“鋸齒”現(xiàn)象,這也由位圖的本質(zhì)特點決定的。

所以在現(xiàn)實中,我們還需要使用到另一種圖像格式:矢量圖。同位圖不 同,矢量圖同位圖的原理不同,矢量圖是利用數(shù)學(xué)公式通過圓,線段等繪制出來的,所以不管如何放大都不會出現(xiàn)變形,但矢量圖不能描述非常復(fù)雜的圖像。所以矢量圖都是用來描述圖形圖案,各種CAD軟件等等都是使用矢量格式來保存文件的。

24位真色位圖轉(zhuǎn)化為8位灰度位圖

(C語言實現(xiàn)) 

//最近在學(xué)習(xí)圖像處理有關(guān)的基礎(chǔ)知識,并試著編程實踐,這樣有助于自己的理解和學(xué)習(xí)。首先遇到的第一個問題就是bmp位圖的基礎(chǔ)知識、bmp位圖的C語言讀入、操作、存入等。以下便是有關(guān)這期間學(xué)習(xí)的知識經(jīng)驗總結(jié):歡迎分享!歡迎建議!謝謝!

//要理解的基礎(chǔ)問題:bmp位圖文件格式(掌握了bmp位圖文件的具體格式后,才有可能更好的對其進(jìn)行編程操作實踐。

位圖文件(bitmap file)保存順序如下:

位圖頭文件(BITMAPFILEHEADER)

位圖信息頭文件(BITMAPINFOHEADER)

調(diào)色板RGBQUAD(真彩色位圖沒有調(diào)色板)

圖像數(shù)據(jù)

##釋義1##位圖頭文件(BITMAPFILEHEADER):

typedef struct tagBITMAPFILEHEADER

{ /*14 bytes BMP文件頭數(shù)據(jù)結(jié)構(gòu)含有BMP文件的類型、

                               文件大小和位圖起始位置等信息*/

    WORD bfType; /*2,位圖文件的類型,必須為BM(0-1字節(jié))*/

    DWORD bfSize; /*4,位圖文件的大小,以字節(jié)為單位(2-5字節(jié))*/

    WORD bfReserved1; /*2,位圖文件保留字,必須為0(6-7字節(jié))*/

    WORD bfReserved2; /*2,位圖文件保留字,必須為0(6-7字節(jié))*/

    DWORD bfOffBits; /*4,位圖數(shù)據(jù)的起始位置,以相對于位圖(10-13字節(jié)) */

}BITMAPFILEHEADER,*PBITMAPFILEHEADER;

##釋義2##位圖信息頭文件(BITMAPINFOHEADER):

typedef struct tagBITMAPINFOHEADER

{ /*40 bytes BMP位圖信息頭數(shù)據(jù)用于說明位圖的尺寸等信息。*/

    DWORD biSize; /*4,本結(jié)構(gòu)所占用字節(jié)數(shù)(14-17字節(jié)) */

    LONG biWidth; /*4,位圖的寬度,以像素為單位(18-21字節(jié))*/

    LONG biHeight; /*4,位圖的高度,以像素為單位(22-25字節(jié)) */

    WORD biPlanes; /*2,目標(biāo)設(shè)備的級別,必須為1(26-27字節(jié)) */

    WORD biBitCount;/*2每個像素所需的位數(shù),必須是1(雙色),(28-29字節(jié))

                          4(16色),8(256色)或24(真彩色)之一 */

    DWORD biCompression;/*4,位圖壓縮類型,必須是 0(不壓縮),(30-33字節(jié))

                       1(BI_RLE8壓縮類型)或2(BI_RLE4壓縮類型)之一 */

    DWORD biSizeImage; /*4,位圖的大小,以字節(jié)為單位(34-37字節(jié)) */

    LONG biXPelsPerMeter;/*4,位圖水平分辨率,每米像素數(shù)(38-41字節(jié)) */

    LONG biYPelsPerMeter; /*4,位圖垂直分辨率,每米像素數(shù)(42-45字節(jié)) */

    DWORD biClrUsed;/*4, 位圖實際使用的顏色表中的顏色數(shù)(46-49字節(jié)) */

    DWORD biClrImportant;/*4,位圖顯示過程中重要的顏色數(shù)(50-53字節(jié)) */

} BITMAPINFOHEADER,*PBITMAPINFOHEADER;

##釋義3##調(diào)色板RGBQUAD(真彩色位圖沒有調(diào)色板):

typedef struct tagRGBQUAD

{ /*顏色表用于說明位圖中的顏色,它有若干個表項

                      ,每一個表項是一個RGBQUAD類型的結(jié)構(gòu),定義一種顏色。*/

    BYTE rgbBlue; /*藍(lán)色的亮度(值范圍為0-255)*/

    BYTE rgbGreen; /*綠色的亮度(值范圍為0-255) */

    BYTE rgbRed;/*紅色的亮度(值范圍為0-255)*/

    BYTE rgbReserved; /*保留,必須為0 */

}RGBQUAD;

##釋義4##圖像數(shù)據(jù):

    對于用到調(diào)色板的位圖,圖像數(shù)據(jù)就是該像素顏色在調(diào)色板中的索引值。對于真彩色圖像,圖像數(shù)據(jù)就是實際的R、G、B值,一個像素由3個字節(jié)24位組成,第一個字節(jié)表示B,第二個字節(jié)表示G,第三個字節(jié)表示R。

    注意:BMP文件是從下到上、從左都右排列的。讀文件時,最先讀到的是圖像的最下面一行的左邊的第一個像素,最后讀到的是最上面一行的最右一個像素。

//C源程序:本C程序由兩部分組成(.c文件和.h文件)。(注:VC6編譯鏈接運(yùn)行通過)

*********************************************************************************************

rgbtogray.h文件:

*****************

/* C語言讀入圖像 位圖文件結(jié)構(gòu)聲明 */

#ifndef BMP_H_INCLUDED

#define BMP_H_INCLUDED



typedef unsigned short WORD;//2*8=16

typedef unsigned long DWORD;//4*8=32

typedef long LONG;//4*8=32

typedef unsigned char BYTE;//1*8=8


#pragma pack(1)

typedef struct tagBITMAPFILEHEADER

{ /*14 bytes BMP文件頭數(shù)據(jù)結(jié)構(gòu)含有BMP文件的類型、

                               文件大小和位圖起始位置等信息*/

    WORD bfType; /*2,位圖文件的類型,必須為BM(0-1字節(jié))*/

    DWORD bfSize; /*4,位圖文件的大小,以字節(jié)為單位(2-5字節(jié))*/

    WORD bfReserved1; /*2,位圖文件保留字,必須為0(6-7字節(jié))*/

    WORD bfReserved2; /*2,位圖文件保留字,必須為0(6-7字節(jié))*/

    DWORD bfOffBits; /*4,位圖數(shù)據(jù)的起始位置,以相對于位圖(10-13字節(jié)) */

}BITMAPFILEHEADER,*PBITMAPFILEHEADER;

#pragma pack()


#pragma pack(1)

typedef struct tagBITMAPINFOHEADER

{ /*40 bytes BMP位圖信息頭數(shù)據(jù)用于說明位圖的尺寸等信息。*/

    DWORD biSize; /*4,本結(jié)構(gòu)所占用字節(jié)數(shù)(14-17字節(jié)) */

    LONG biWidth; /*4,位圖的寬度,以像素為單位(18-21字節(jié))*/

    LONG biHeight; /*4,位圖的高度,以像素為單位(22-25字節(jié)) */

    WORD biPlanes; /*2,目標(biāo)設(shè)備的級別,必須為1(26-27字節(jié)) */

    WORD biBitCount;/*2每個像素所需的位數(shù),必須是1(雙色),(28-29字節(jié))

                          4(16色),8(256色)或24(真彩色)之一 */

    DWORD biCompression;/*4,位圖壓縮類型,必須是 0(不壓縮),(30-33字節(jié))

                       1(BI_RLE8壓縮類型)或2(BI_RLE4壓縮類型)之一 */

    DWORD biSizeImage; /*4,位圖的大小,以字節(jié)為單位(34-37字節(jié)) */

    LONG biXPelsPerMeter;/*4,位圖水平分辨率,每米像素數(shù)(38-41字節(jié)) */

    LONG biYPelsPerMeter; /*4,位圖垂直分辨率,每米像素數(shù)(42-45字節(jié)) */

    DWORD biClrUsed;/*4, 位圖實際使用的顏色表中的顏色數(shù)(46-49字節(jié)) */

    DWORD biClrImportant;/*4,位圖顯示過程中重要的顏色數(shù)(50-53字節(jié)) */

} BITMAPINFOHEADER,*PBITMAPINFOHEADER;

#pragma pack()


#pragma pack(1)

typedef struct tagRGBQUAD

{ /*顏色表用于說明位圖中的顏色,它有若干個表項

                      ,每一個表項是一個RGBQUAD類型的結(jié)構(gòu),定義一種顏色。*/

    BYTE rgbBlue; /*藍(lán)色的亮度(值范圍為0-255)*/

    BYTE rgbGreen; /*綠色的亮度(值范圍為0-255) */

    BYTE rgbRed;/*紅色的亮度(值范圍為0-255)*/

    BYTE rgbReserved; /*保留,必須為0 */

}RGBQUAD;/*顏色表中RGBQUAD結(jié)構(gòu)數(shù)據(jù)的個數(shù)有biBitCount來確定:

   當(dāng)biBitCount=1,4,8時,分別有2,16,256個表項;

   當(dāng)biBitCount=24時,沒有顏色表項。*/

#pragma pack()


#pragma pack(1)

typedef struct tagBITMAPIMAGE

{ /*位圖信息頭和顏色表組成位圖信息*/

    BITMAPFILEHEADER bmiHeader; /*位圖信息頭*/

    RGBQUAD bmiColors[1]; /*顏色表*/

}BITMAPIMAGE;

#pragma pack()


#endif

*********************************************************************************************

rgbtogray.h文件:

******************

/*******************************************************************************/

#include<stdio.h>

#include<stdlib.h>

#include<malloc.h>

#include<string.h>

/********************************************************************/

//自定義的有關(guān)圖像處理的頭文件為rgbtogray.h


//系統(tǒng)定義有關(guān)圖像處理的頭文件為windows.h


//目前,引用系統(tǒng)的windows.h程序工作正常,但自己的頭文件有問題,待改正!


//最終實現(xiàn)引用自己的頭文件rgbtogray.h


//太棒了:頭文件的問題終于解決了


  //#include<windows.h>


#include "rgbtogray.h"

/********************************************************************/

/*****************************************************************************/

//全局變量聲明


FILE * fpSrcBmpfile;//定義文件指針,用于讀入和存儲圖像文件


FILE * fpDestBmpfile;


/******************************************************************************/

//程序子函數(shù)聲明


void GetBmpHeader(PBITMAPFILEHEADER, PBITMAPINFOHEADER);//獲得位圖的文件頭和信息頭


void ChangeBmpHeader(PBITMAPFILEHEADER, PBITMAPINFOHEADER, WORD);//改變位圖的文件頭和信息頭


void SetBmpHeader(const PBITMAPFILEHEADER, const PBITMAPINFOHEADER);//將修改后的文件頭和信息頭存入新位圖文件


void SetRGBQUAD();//建立顏色板并存入灰度圖文件中


int RgbToGray();//24位真色圖轉(zhuǎn)化為8位灰度圖的主要函數(shù)



/******************************************************************************/

//主函數(shù)框架,菜單。ǚ奖阏{(diào)用其他程序,以便拓展)


void main()

{

    int command=1;

    while(command)//菜單選項,可拓展


    {

    printf("\n*****************************Image Processing Menu***************************\n");

    printf("|--------1:RGB To GRAY transform!--------|\n");

    printf("|--------0:End!---------|\n");

    printf("*****************************************************************************\n");    

    printf("Hint:Processor Number?\n");

    scanf("%d",&command);

        switch(command)

        {

        case 1:

            RgbToGray();

            break;

        case 0:

            printf("---Bye-bye---\n");

            break;

        default:

            printf("---Not defined number!\n");

            break;

        }    

    }

}


/******************************************************************************/

//函數(shù)體部分(副)


void GetBmpHeader(PBITMAPFILEHEADER pbfheader, PBITMAPINFOHEADER pbiheader)

{

    fread(pbfheader, sizeof(BITMAPFILEHEADER), 1,fpSrcBmpfile);

    fread(pbiheader, sizeof(BITMAPINFOHEADER), 1,fpSrcBmpfile);

}

void ChangeBmpHeader(PBITMAPFILEHEADER pbfheader, PBITMAPINFOHEADER pbiheader, WORD wType)

{

    pbiheader->biBitCount = wType; // 24 或者 8


    pbiheader->biClrUsed = (wType == 24) ? 0 : 256;

    pbfheader->bfOffBits = 54 + pbiheader->biClrUsed * sizeof(RGBQUAD);

    pbiheader->biSizeImage = ((((pbiheader->biWidth * pbiheader->biBitCount) + 31) & ~31) / 8) * pbiheader->biHeight;

    pbfheader->bfSize = pbfheader->bfOffBits + pbiheader->biSizeImage;

}

void SetBmpHeader(const PBITMAPFILEHEADER pbfheader, const PBITMAPINFOHEADER pbiheader)

{

    fwrite(pbfheader, sizeof(BITMAPFILEHEADER), 1, fpDestBmpfile);

    fwrite(pbiheader, sizeof(BITMAPINFOHEADER), 1, fpDestBmpfile);

}

void SetRGBQUAD()

{

    int i;

    RGBQUAD rgbquad[256];

    for(i=0;i<256;i++) {

        rgbquad[i].rgbBlue = i;

        rgbquad[i].rgbGreen = i;

        rgbquad[i].rgbRed = i;

        rgbquad[i].rgbReserved = 0;

    }

    fwrite(rgbquad, 256 * sizeof(RGBQUAD), 1, fpDestBmpfile);

}

/******************************************************************************/

//函數(shù)體部分(主)


int RgbToGray()

{

    LONG w,h;

    BYTE r,g,b;

    BYTE gray;

    BYTE count24,count8;

    BYTE Bmpnul=0;


    char SrcBmpfile[256];

    char DestBmpfile[256];

    BITMAPFILEHEADER bmfh; // bmp文件頭


    BITMAPINFOHEADER bmih; // 位圖信息頭


    BYTE *data;


    memset(&bmfh, 0, sizeof(BITMAPFILEHEADER));//內(nèi)存初始化


    memset(&bmih, 0, sizeof(BITMAPINFOHEADER));

    data=(BYTE *)malloc(3*sizeof(BYTE));

    if(!data)

        {

           printf("Error:Can not allocate memory .\n");

           free(data);

           return -1;

        }


    getchar();

    printf("Input the path of SrcBmpfile:\n");

    gets(SrcBmpfile);


    if((fpSrcBmpfile=fopen(SrcBmpfile,"rb"))==NULL) 

    {

        printf("Error:Open the file of SrcBmpfile failed!\n");//輸入源位圖文件


        free(data);

        return -1;

    }

    rewind(fpSrcBmpfile);

    GetBmpHeader(&bmfh,&bmih);

//ceshie_start


    printf("The contents in the file header of the BMP file:\n");

    printf("bfType:%ld\n",bmfh.bfType);

    printf("bfSize:%ld\n",bmfh.bfSize);

    printf("bfReserved1:%ld\n",bmfh.bfReserved1);

    printf("bfReserved2:%ld\n",bmfh.bfReserved2);

    printf("bfOffBits:%ld\n",bmfh.bfOffBits);

    printf("The contents in the info header:\n");

    printf("biSize:%ld\n",bmih.biSize);

//ceshi_end


    if(bmfh.bfType!=0x4D42)

    {

        printf("Error:This file is not bitmap file!\n");

        free(data);

        return -1;

    }

    if(bmih.biBitCount!=24)

    {

        printf("Error:This bmpfile is not 24bit bitmap!\n");

        free(data);

        return -1;

    }

    if(bmih.biCompression!=0)

    {

        printf("Error:This 8bit bitmap file is not BI_RGB type!\n");

        free(data);

        return -1;

    }


    printf("Input the path of the DestBmpfile:\n");//輸入目標(biāo)位圖文件


    gets(DestBmpfile);


    if((fpDestBmpfile=fopen(DestBmpfile,"wb"))==NULL)

    {

        printf("Error:Open the file of DestBmpfile failed!\n");

        free(data);

        return -1;

    }


    ChangeBmpHeader(&bmfh,&bmih,8);

    SetBmpHeader(&bmfh,&bmih);

    SetRGBQUAD();


    count24=(4-(bmih.biWidth*3)%4)%4;

    count8=(4-(bmih.biWidth)%4)%4;


    for(h=bmih.biHeight-1;h>=0;h--)

    {

        for(w=0;w<bmih.biWidth;w++)

        {

            fread(data,3,1,fpSrcBmpfile);

            if(feof(fpSrcBmpfile))

            {

                printf("Error:Read Pixel data failed!\n");

                free(data);

                return -1;

            }

            b=*data;

            g=*(data+1);

            r=*(data+2);

            gray=(299*r+587*g+114*b)/1000;

            //if(gray>120)gray=250;


            fwrite(&gray,sizeof(gray),1,fpDestBmpfile);

        }

        fseek(fpSrcBmpfile,count24,SEEK_CUR);

        fwrite(&Bmpnul,1,count8,fpDestBmpfile);

    }

    printf("Hint:Convert RGB To GRAY Successfully!\n");

    free(data);//釋放內(nèi)存空間


    fclose(fpDestBmpfile);//關(guān)閉文件指針


    fclose(fpSrcBmpfile);

    return 0;

}

/******************************************************************************/

*******************************************************************************************

****當(dāng)時困擾了本人很長時間的一個程序問題,最后終于解決:

#prama pack(n)

結(jié)構(gòu)體定義;

#prama pack()

##釋義##:關(guān)于struct的使用方法:

     struct是一種復(fù)合數(shù)據(jù)類型,其構(gòu)成元素既可以是基本數(shù)據(jù)類型(如int、long、float等)的變量,也可以是一些復(fù)合數(shù)據(jù)類型(如array、struct、union等)的數(shù)據(jù)單元。對于結(jié)構(gòu)體,編譯器會自動進(jìn)行成員變量的對齊,以提高運(yùn)算效率。缺省情況下,編譯器為結(jié)構(gòu)體的每個成員按其自然對界(natural alignment)條件分配空間。各個成員按照它們被聲明的順序在內(nèi)存中順序存儲,第一個成員的地址和整個結(jié)構(gòu)的地址相同。

    自然對界是指按結(jié)構(gòu)體的成員中size最大的成員對齊。

#pragma pack規(guī)定的對齊長度,實際使用的規(guī)則是:

    結(jié)構(gòu),聯(lián)合,或者類的數(shù)據(jù)成員,第一個放在偏移為0的地方,以后每個數(shù)據(jù)成員的對齊,按照#pragma pack指定的數(shù)值和結(jié)構(gòu)體的自然對齊長度中比較小的那個進(jìn)行。

    也就是說,當(dāng)#pragma pack的值等于或超過所有數(shù)據(jù)成員長度的時候,這個值的大小將不產(chǎn)生任何效果。

    結(jié)構(gòu)體的對齊,按照結(jié)構(gòu)體中size最大的數(shù)據(jù)成員和#pragma pack指定值之間,較小的那個進(jìn)行。

軟件標(biāo)簽: bmp位圖 灰度圖

其他版本下載

發(fā)表評論

昵稱:
表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
查看所有(0)條評論 > 字?jǐn)?shù): 0/500

TOP
軟件下載