千家信息网

C语言如何实现BMP格式图片转化为灰度

发表于:2025-11-17 作者:千家信息网编辑
千家信息网最后更新 2025年11月17日,小编给大家分享一下C语言如何实现BMP格式图片转化为灰度,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!代码如下:#include#include#include #pragma p
千家信息网最后更新 2025年11月17日C语言如何实现BMP格式图片转化为灰度

小编给大家分享一下C语言如何实现BMP格式图片转化为灰度,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

代码如下:

#include#include#include  #pragma pack(1)typedef struct tagBITMAPFILEHEADER{    unsigned char bfType[2];//文件格式    unsigned long bfSize;//文件大小    unsigned short bfReserved1;//保留    unsigned short bfReserved2;    unsigned long bfOffBits; //DIB数据在文件中的偏移量}fileHeader;#pragma pack()/*位图数据信息结构*/#pragma pack(1)typedef struct tagBITMAPINFOHEADER{    unsigned long biSize;//该结构的大小    long biWidth;//文件宽度    long biHeight;//文件高度    unsigned short biPlanes;//平面数    unsigned short biBitCount;//颜色位数    unsigned long biCompression;//压缩类型    unsigned long biSizeImage;//DIB数据区大小    long biXPixPerMeter;    long biYPixPerMeter;    unsigned long biClrUsed;//多少颜色索引表    unsigned long biClrImporant;//多少重要颜色}fileInfo;#pragma pack()/*调色板结构*/#pragma pack(1)typedef struct tagRGBQUAD{    unsigned char rgbBlue; //蓝色分量亮度    unsigned char rgbGreen;//绿色分量亮度    unsigned char rgbRed;//红色分量亮度    unsigned char rgbReserved;}rgbq;#pragma pack() int main(){    FILE *fp1 = fopen("C:\\Users\\Administrator\\Desktop\\data\\bmp\\image.bmp", "rb+");    if (fp1 == NULL)    {        printf("打开文件fp1失败");        exit(0);    }     FILE *fp2 = fopen("C:\\Users\\Administrator\\Desktop\\data\\bmp\\imageGray.bmp", "wb");    if (fp1 == NULL)    {        printf("打开文件fp2失败");        exit(0);    }     fileHeader * fh;    fileInfo * fi;    fh = (fileHeader *)malloc(sizeof(fileHeader));    fi = (fileInfo *)malloc(sizeof(fileInfo));     //读取位图头结构和信息头    fread(fh, sizeof(fileHeader), 1, fp1);    fread(fi, sizeof(fileInfo), 1, fp1);     printf("\\\\\\\\\\\\\\\\\\\\原始图片信息\\\\\\\\\\\\\\\\\\\\\\\\\\\n");    printf("bmp文件头:\n");    printf("bfSize:%d\n", fh->bfSize);    printf("bfOffBits:%d\n", fh->bfOffBits);    printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");    printf("bmp信息头\n");    printf("结构体长度:%d \n", fi->biSize);    printf("位图宽度:%d \n", fi->biWidth);    printf("位图高度:%d \n", fi->biHeight);    printf("位图平面数:%d \n", fi->biPlanes);    printf("颜色位数:%d \n", fi->biBitCount);    printf("压缩方式:%d \n", fi->biCompression);    printf("实际位图数据占用的字节数:%d \n", fi->biSizeImage);    printf("X方向分辨率:%d \n", fi->biXPixPerMeter);    printf("Y方向分辨率:%d \n", fi->biYPixPerMeter);    printf("使用的颜色数:%d \n", fi->biClrUsed);    printf("重要颜色数:%d \n", fi->biClrImporant);    printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");     //修改信息头    fi->biBitCount = 8;    //fi->biSizeImage = ((fi->biWidth * 3 + 3) / 4) * 4 * fi->biHeight;    fi->biSizeImage = fi->biHeight*fi->biWidth;    //修改文件头    fh->bfOffBits = sizeof(fileHeader) + sizeof(fileInfo) + 256 * sizeof(rgbq);    fh->bfSize = fh->bfOffBits + fi->biSizeImage;     printf("\\\\\\\\\\\\\\\\\\\\修改后的图片信息\\\\\\\\\\\\\\\\\\\\\\\\\\\n");    printf("bmp文件头:\n");    printf("bfSize:%d\n", fh->bfSize);    printf("bfOffBits:%d\n", fh->bfOffBits);    printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");    printf("bmp信息头\n");    printf("结构体长度:%d \n", fi->biSize);    printf("位图宽度:%d \n", fi->biWidth);    printf("位图高度:%d \n", fi->biHeight);    printf("位图平面数:%d \n", fi->biPlanes);    printf("颜色位数:%d \n", fi->biBitCount);    printf("压缩方式:%d \n", fi->biCompression);    printf("实际位图数据占用的字节数:%d \n", fi->biSizeImage);    printf("X方向分辨率:%d \n", fi->biXPixPerMeter);    printf("Y方向分辨率:%d \n", fi->biYPixPerMeter);    printf("使用的颜色数:%d \n", fi->biClrUsed);    printf("重要颜色数:%d \n", fi->biClrImporant);    printf("\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\n");     //创建调色板    int i,j,k=0;    rgbq *fq = (rgbq *)malloc(256 * sizeof(rgbq));    for (i = 0; i<256; i++)    {        fq[i].rgbBlue = fq[i].rgbGreen = fq[i].rgbRed = i;    }    //写入文件头、信息头、调色板    fwrite(fh, sizeof(fileHeader), 1, fp2);    fwrite(fi, sizeof(fileInfo), 1, fp2);    fwrite(fq, sizeof(rgbq), 256, fp2);     //将位图信息转为灰度    //存储bmp一行的像素点    //unsigned char ImgData[900][3];    unsigned char ImgData[3000][3];    //将灰度图像存到一维数组中    //unsigned char grayData2[900];    unsigned char ImgData2[3000];    /*    //错误的算法    for (i = 0; i < fi->biHeight; i++)    {        for (j = 0; j < (fi->biWidth * 3 + 3) / 4 * 4; j++)        {            for (k = 0; k < 3; k++)            {                fread(&ImgData[j][k], 1, 1, fp1);            }        }        for (j = 0; j < (fi->biWidth + 3) / 4 * 4; j++)        {            ImgData2[j] = int((float)ImgData[j][0] * 0.114 +                (float)ImgData[j][1] * 0.587 +                (float)ImgData[j][2] * 0.299);        }        //将灰度图信息写入        fwrite(ImgData2, j, 1, fp2);    }    */    /*    //正确的算法(1)    for (i = 0; ibiHeight; i++)    {        for (j = 0; j<(fi->biWidth + 3) / 4 * 4; j++)        {            for (k = 0; k<3; k++)            fread(&ImgData[j][k], 1, 1, fp1);        }        for (j = 0; j<(fi->biWidth + 3) / 4 * 4; j++)        {            ImgData2[j] = int((float)ImgData[j][0] * 0.114 +                (float)ImgData[j][1] * 0.587 +                (float)ImgData[j][2] * 0.299);        }        //将灰度图信息写入        fwrite(ImgData2, j, 1, fp2);    }    */    //正确算法(2)    unsigned char * * bmp_data;    bmp_data = new unsigned char*[fi->biHeight]; //声明一个指针数组    unsigned char *data288 = new unsigned char[fi->biHeight*fi->biWidth];     for (i = 0; ibiHeight; i++)        bmp_data[i] = new unsigned char[(fi->biWidth * 3 + 3) / 4 * 4]; //每个数组元素也是一个指针数组    for (i = 0; ibiHeight; i++)        for (j = 0; j<(fi->biWidth * 3 + 3) / 4 * 4; j++)            fread(&bmp_data[i][j], 1, 1, fp1);//每次只读取一个字节,存入数组     for (i = 0; ibiHeight; i++)//将24位真彩色转换成灰度图        for (j = 0; jbiWidth; j++){        data288[fi->biWidth*i + j] = ((unsigned char)((float)bmp_data[i][3 * j] * 0.114 + (float)bmp_data[i][3 * j + 1] * 0.587 + (float)bmp_data[i][3 * j + 2] * 0.299));        }     fwrite(data288, fi->biSizeImage, 1, fp2);    free(fh);    free(fi);    free(fq);    fclose(fp1);    fclose(fp2);    printf("success\n");    return 0;}

看完了这篇文章,相信你对"C语言如何实现BMP格式图片转化为灰度"有了一定的了解,如果想了解更多相关知识,欢迎关注行业资讯频道,感谢各位的阅读!

0