24位bmp图修改为灰度图

注意 数据类型占内存大小[各个系统不一样..]会导致读取数据有问题...
typedef unsigned char BYTE;//字符型
typedef unsigned short WORD;//短整型
typedef int DWORD;//长整形
typedef int LONG;
/*bmp文件信息头*/
typedef struct BItMAPFILEHEADER
{
    WORD bfType;
    DWORD bfSize;
    WORD bfReserved1;
    WORD bfReserved2;
    DWORD bfOffBits;
}BITMAPFILEHEADER;
/*位图信息头 */
typedef struct BIiMAPINFOHEADER
{
    DWORD biSize;
    LONG biWidth;
    LONG biHeight;
    WORD biPlanes;
    WORD biBitCount;
    DWORD biCompression;            //压缩方式压缩方式    DWORD biSizeImage;
    DWORD biSizeImage;              //位图数据长度
    LONG biXPelsPerMeter;
    LONG biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
    
}BITMAPINFOHEADER;
///*RGB调色版*/
//typedef struct tagRGBQUAD {
//    BYTE    rgbBlue;
//    BYTE    rgbGreen;
//    BYTE    rgbRed;
//    BYTE    rgbReserved;
//} RGBQUAD;

/*16位图数据*/
typedef  struct rgbDATA16
{
    
}RGBDATA16;
/*24位图数据*/
typedef struct rgbDATA24            /*三字节存放一个点像素*/
{
    BYTE rgbRed;
    BYTE rgbGreen;
    BYTE rgBlue;
}RGBDATA24;
typedef struct rgbDATA32
{
    BYTE rgbRed;
    BYTE rgbGreen;
    BYTE rgBlue;
    BYTE rgbAlpha;
    BYTE rgbVifrification;       //透明色
}RGBDATA32;
int main(int argc, const char * argv[])
{
    BITMAPFILEHEADER fileHeadT={0};
    BITMAPINFOHEADER infoHead={0};
    FILE *FE=fopen("/WWW1.bmp", "rb");
    FILE *FE2=fopen("/Users/DaleHui/Desktop/WWW222.bmp", "wb+");

    
    /*bmp文件信息头读取*/
    fread(&fileHeadT, sizeof(BITMAPFILEHEADER), 1, FE);
    /*位图信息头*/
    fread(&infoHead,sizeof(BITMAPINFOHEADER) , 1, FE);
    
        printf("位图数据长度%d",infoHead.biSizeImage);
    
    
    if (fileHeadT.bfType!=0x4d42) {
        printf("不是bmp文件");
        fclose(FE);
        return 0;
    }
    if (infoHead.biBitCount==16||infoHead.biBitCount==24||infoHead.biBitCount==32) {
        printf("该bmp不存在调色版\n");
    }
    printf("%s \n",infoHead.biCompression==0?"无压缩":"该图已压缩");

    RGBDATA24 *rgb24;
    rgb24=calloc(infoHead.biSizeImage/3, sizeof(RGBDATA24));  //存放位图数据用的堆
    
    int i=0;
    while (i<infoHead.biSizeImage/3) {
        fread((rgb24+i), sizeof(RGBDATA24), 1, FE);
          (rgb24+i)->rgbGreen=(rgb24+i)->rgBlue=(rgb24+i)->rgbRed=((rgb24+i)->rgbGreen+(rgb24+i)->rgBlue+(rgb24+i)->rgbRed)/3;
        i++;
    }
    
    
    fwrite(&fileHeadT, sizeof(BITMAPFILEHEADER), 1, FE2);
    fwrite(&infoHead, sizeof(BITMAPINFOHEADER), 1, FE2);

    
    int j=0;
    while ((j)<infoHead.biSizeImage/3) {
        fwrite((rgb24+j), sizeof(RGBDATA24), 1, FE2);
        j++;
    }
    
    free(rgb24);
    fclose(FE2);
    fclose(FE);
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个将24BMP片转换为8BMP片的示例代码。这里使用了Windows API来读取和写入BMP文件,因此需要包含Windows.h头文件。 ``` #include <Windows.h> int main() { // 打开24BMP文件 HANDLE hFile = CreateFile(L"input.bmp", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { printf("无法打开文件\n"); return 1; } // 读取BMP文件头信息 BITMAPFILEHEADER bmpFileHeader; DWORD dwBytesRead; if (!ReadFile(hFile, &bmpFileHeader, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL) || dwBytesRead != sizeof(BITMAPFILEHEADER)) { printf("无法读取文件头\n"); CloseHandle(hFile); return 1; } // 读取BMP信息头信息 BITMAPINFOHEADER bmpInfoHeader; if (!ReadFile(hFile, &bmpInfoHeader, sizeof(BITMAPINFOHEADER), &dwBytesRead, NULL) || dwBytesRead != sizeof(BITMAPINFOHEADER)) { printf("无法读取信息头\n"); CloseHandle(hFile); return 1; } // 只支持24BMP if (bmpInfoHeader.biBitCount != 24) { printf("不支持的数\n"); CloseHandle(hFile); return 1; } // 读取调色板信息 RGBQUAD palette[256]; if (!ReadFile(hFile, palette, sizeof(RGBQUAD) * 256, &dwBytesRead, NULL) || dwBytesRead != sizeof(RGBQUAD) * 256) { printf("无法读取调色板\n"); CloseHandle(hFile); return 1; } // 计算调色板中各颜色的灰度值 BYTE grayTable[256]; for (int i = 0; i < 256; i++) { grayTable[i] = (BYTE)(0.299 * palette[i].rgbRed + 0.587 * palette[i].rgbGreen + 0.114 * palette[i].rgbBlue); } // 读取像素数据 BYTE* pixelData = (BYTE*)malloc(bmpInfoHeader.biSizeImage); if (!ReadFile(hFile, pixelData, bmpInfoHeader.biSizeImage, &dwBytesRead, NULL) || dwBytesRead != bmpInfoHeader.biSizeImage) { printf("无法读取像素数据\n"); CloseHandle(hFile); free(pixelData); return 1; } // 关闭24BMP文件 CloseHandle(hFile); // 创建8BMP文件 HANDLE hNewFile = CreateFile(L"output.bmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hNewFile == INVALID_HANDLE_VALUE) { printf("无法创建文件\n"); free(pixelData); return 1; } // 写入BMP文件头信息 BITMAPFILEHEADER newBmpFileHeader = bmpFileHeader; newBmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256 + bmpInfoHeader.biWidth * bmpInfoHeader.biHeight; newBmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256; if (!WriteFile(hNewFile, &newBmpFileHeader, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL) || dwBytesRead != sizeof(BITMAPFILEHEADER)) { printf("无法写入文件头\n"); CloseHandle(hNewFile); free(pixelData); return 1; } // 写入BMP信息头信息 BITMAPINFOHEADER newBmpInfoHeader = bmpInfoHeader; newBmpInfoHeader.biBitCount = 8; newBmpInfoHeader.biClrUsed = 256; newBmpInfoHeader.biSizeImage = bmpInfoHeader.biWidth * bmpInfoHeader.biHeight; if (!WriteFile(hNewFile, &newBmpInfoHeader, sizeof(BITMAPINFOHEADER), &dwBytesRead, NULL) || dwBytesRead != sizeof(BITMAPINFOHEADER)) { printf("无法写入信息头\n"); CloseHandle(hNewFile); free(pixelData); return 1; } // 写入调色板信息 if (!WriteFile(hNewFile, palette, sizeof(RGBQUAD) * 256, &dwBytesRead, NULL) || dwBytesRead != sizeof(RGBQUAD) * 256) { printf("无法写入调色板\n"); CloseHandle(hNewFile); free(pixelData); return 1; } // 将像素数据转换为8颜色编号,并写入文件 for (int i = 0; i < bmpInfoHeader.biSizeImage; i += 3) { BYTE grayValue = (BYTE)(0.299 * pixelData[i + 2] + 0.587 * pixelData[i + 1] + 0.114 * pixelData[i]); BYTE colorIndex = 0; for (int j = 0; j < 256; j++) { if (grayValue >= grayTable[j]) { colorIndex = j; } else { break; } } if (!WriteFile(hNewFile, &colorIndex, 1, &dwBytesRead, NULL) || dwBytesRead != 1) { printf("无法写入像素\n"); CloseHandle(hNewFile); free(pixelData); return 1; } } // 关闭8BMP文件 CloseHandle(hNewFile); free(pixelData); return 0; } ``` 这个示例代码中,将24BMP片的RGB像素数据转换为灰度值的计算公式采用了常见的"NTSC"标准。实际使用中,可以根据需要使用其他公式。同时,如果需要处理的是其他数的BMP片,需要根据其格式进行相应的修改
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值