请你用c语言写一段代码,实现以下功能:读取一张bmp格式的图像,每个像素点是32位的,分别是a,r,g,b四个分量,每个分量8比特。将每个分量提取出来,并分别保存在四个数组中,并将他们分别打印到4个txt文件中,每个数以逗号隔开,每在txt文件中打印满一行像素,就换行。
时间: 2023-05-19 18:05:06 浏览: 245
8位bmp图像的读写 代码
以下是实现该功能的C语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma pack(1) // 确保结构体按照1字节对齐
// BMP文件头结构体
typedef struct {
char bfType[2]; // 文件类型,必须为"BM"
int bfSize; // 文件大小,单位为字节
short bfReserved1; // 保留字段,必须为0
short bfReserved2; // 保留字段,必须为0
int bfOffBits; // 数据偏移量,即位图数据从文件头开始的偏移量
} BMPFILEHEADER;
// BMP信息头结构体
typedef struct {
int biSize; // 信息头大小,必须为40
int biWidth; // 图像宽度,单位为像素
int biHeight; // 图像高度,单位为像素
short biPlanes; // 位平面数,必须为1
short biBitCount; // 每个像素的位数,必须为32
int biCompression; // 压缩类型,必须为0
int biSizeImage; // 图像数据大小,单位为字节
int biXPelsPerMeter; // 水平分辨率,单位为像素/米
int biYPelsPerMeter; // 垂直分辨率,单位为像素/米
int biClrUsed; // 颜色表中实际使用的颜色数,必须为0
int biClrImportant; // 重要的颜色数,必须为0
} BMPINFOHEADER;
// 像素结构体
typedef struct {
unsigned char b; // 蓝色分量
unsigned char g; // 绿色分量
unsigned char r; // 红色分量
unsigned char a; // Alpha分量
} PIXEL;
int main() {
char bmpFileName[256]; // BMP文件名
printf("请输入BMP文件名:");
scanf("%s", bmpFileName);
FILE* bmpFile = fopen(bmpFileName, "rb"); // 以二进制只读方式打开BMP文件
if (!bmpFile) {
printf("打开BMP文件失败!\n");
return 0;
}
BMPFILEHEADER fileHeader;
BMPINFOHEADER infoHeader;
// 读取BMP文件头和信息头
fread(&fileHeader, sizeof(BMPFILEHEADER), 1, bmpFile);
fread(&infoHeader, sizeof(BMPINFOHEADER), 1, bmpFile);
// 检查BMP文件是否合法
if (strncmp(fileHeader.bfType, "BM", 2) != 0 || infoHeader.biBitCount != 32) {
printf("不支持的BMP文件格式!\n");
fclose(bmpFile);
return 0;
}
// 计算每行像素所占的字节数
int rowSize = ((infoHeader.biWidth * infoHeader.biBitCount + 31) / 32) * 4;
// 分配像素数组内存
PIXEL* pixels = (PIXEL*)malloc(infoHeader.biHeight * rowSize);
// 读取像素数据
fseek(bmpFile, fileHeader.bfOffBits, SEEK_SET);
fread(pixels, infoHeader.biHeight * rowSize, 1, bmpFile);
// 关闭BMP文件
fclose(bmpFile);
// 分别保存四个分量的数组和文件名
unsigned char* aArray = (unsigned char*)malloc(infoHeader.biWidth * infoHeader.biHeight);
unsigned char* rArray = (unsigned char*)malloc(infoHeader.biWidth * infoHeader.biHeight);
unsigned char* gArray = (unsigned char*)malloc(infoHeader.biWidth * infoHeader.biHeight);
unsigned char* bArray = (unsigned char*)malloc(infoHeader.biWidth * infoHeader.biHeight);
char aFileName[256], rFileName[256], gFileName[256], bFileName[256];
sprintf(aFileName, "%s_a.txt", bmpFileName);
sprintf(rFileName, "%s_r.txt", bmpFileName);
sprintf(gFileName, "%s_g.txt", bmpFileName);
sprintf(bFileName, "%s_b.txt", bmpFileName);
// 提取每个像素的四个分量,并保存到对应的数组中
for (int y = 0; y < infoHeader.biHeight; y++) {
for (int x = 0; x < infoHeader.biWidth; x++) {
PIXEL* pixel = &pixels[y * rowSize / 4 + x];
aArray[y * infoHeader.biWidth + x] = pixel->a;
rArray[y * infoHeader.biWidth + x] = pixel->r;
gArray[y * infoHeader.biWidth + x] = pixel->g;
bArray[y * infoHeader.biWidth + x] = pixel->b;
}
}
// 打开四个txt文件并将分量数组中的数据写入
FILE* aFile = fopen(aFileName, "w");
FILE* rFile = fopen(rFileName, "w");
FILE* gFile = fopen(gFileName, "w");
FILE* bFile = fopen(bFileName, "w");
for (int y = 0; y < infoHeader.biHeight; y++) {
for (int x = 0; x < infoHeader.biWidth; x++) {
fprintf(aFile, "%d,", aArray[y * infoHeader.biWidth + x]);
fprintf(rFile, "%d,", rArray[y * infoHeader.biWidth + x]);
fprintf(gFile, "%d,", gArray[y * infoHeader.biWidth + x]);
fprintf(bFile, "%d,", bArray[y * infoHeader.biWidth + x]);
if (x == infoHeader.biWidth - 1) {
fprintf(aFile, "\n");
fprintf(rFile, "\n");
fprintf(gFile, "\n");
fprintf(bFile, "\n");
}
}
}
// 关闭四个txt文件
fclose(aFile);
fclose(rFile);
fclose(gFile);
fclose(bFile);
// 释放内存
free(pixels);
free(aArray);
free(rArray);
free(gArray);
free(bArray);
printf("分量已保存到%s_a.txt、%s_r.txt、%s_g.txt、%s_b.txt中!\n", bmpFileName, bmpFileName, bmpFileName, bmpFileName);
return 0;
}
```
该代码可以读取指定的BMP文件,提取每个像素的四个分量,并分别保存到四个txt文件中。每个数以逗号隔开,每在txt文件中打印满一行像素,就换行。
阅读全文