C語言實現BMP格式圖片轉化為灰度
本文實例為大傢分享瞭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]; /* //錯誤的算法 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; i<fi->biHeight; 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; 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; }
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- C語言實現24位彩色圖像二值化
- 如何通過UltraEdit解析BMP文件內部結構(BMP位圖基礎)
- C語言實現BMP圖像處理(彩色圖轉灰度圖)
- C++實現bmp格式圖像讀寫
- C語言實現bmp圖像平移操作