本文实例为大家分享了C语言将BMP格式图片转化为灰度的具体代码,供大家参考,具体内容如下
代码如下:
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#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];
//正确算法(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; i<fi->biHeight; i++)
bmp_data[i] = new unsigned char[(fi->biWidth * 3 + 3) / 4 * 4]; //每个数组元素也是一个指针数组
for (i = 0; i<fi->biHeight; i++)
for (j = 0; j<(fi->biWidth * 3 + 3) / 4 * 4; j++)
fread(&bmp_data[i][j], 1, 1, fp1);//每次只读取一个字节,存入数组
for (i = 0; i<fi->biHeight; i++)//将24位真彩色转换成灰度图
for (j = 0; j<fi->biWidth; 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;
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。