在上一篇文章 讀取bmp格式位圖文件到二維數組(C語言) 中已經實現了讀取24bits Bmp位圖文件到二維數組的過程。
這次接着上一次的工作,試着用C語言將數據寫入位圖文件中。
基本原理和讀取文件是類似的,只不過我們要把上次使用的fread換成fwrite:
1.寫入文件頭:
fwrite(fileHead, sizeof(BITMAPFILEHEADER), 1, fp);
2.寫入信息頭:
fwrite(infoHead, sizeof(BITMAPINFOHEADER), 1, fp);
3.循環寫入像素信息:
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
fwrite(&data[i][j], sizeof(RGBDATA), 1, fp);
}
}
代碼如下:
FILE* saveMatrixToBmpFile(BITMAPFILEHEADER* fileHead, BITMAPINFOHEADER* infoHead, RGBDATA** data,FILE* fp) {
int bitsPerPixel = infoHead->bBitsPerPixel;
if (bitsPerPixel != 24) {
fprintf(stderr, "本功能目前只適用於24位位圖");
return NULL;
}
int width = infoHead->bImageWidth;
int height = infoHead->bImageHeight;
printf("初始:%d\n", ftell(fp));
fwrite(fileHead, sizeof(BITMAPFILEHEADER), 1, fp);
printf("寫入文件頭:%d\n", ftell(fp));
fwrite(infoHead, sizeof(BITMAPINFOHEADER), 1, fp);
printf("寫入信息頭:%d\n", ftell(fp));
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
fwrite(&data[i][j], sizeof(RGBDATA), 1, fp);
}
}
printf("寫入像素:%d\n", ftell(fp));
return fp;
}
再實現一個函數用來實現圖像翻轉:(交換二維數組的行指針)
代碼如下:
RGBDATA** flipMatrix(RGBDATA** data, int n) {
int i = 0;
int j = n-1;
while (i < j) {
RGBDATA* temp = data[j];
data[j] = data[i];
data[i] = temp;
i++;
j--;
}
return data;
}
有了這兩個函數,我們就可以試着讀取一個bmp圖片,將其繞x軸翻轉再存入文件了:
int main() {
FILE* fp = openBmpImage("lena.bmp","r");
BITMAPFILEHEADER* fileHead = readBmpFileHead(fp);
BITMAPINFOHEADER* infoHead = readBmpInfoHead(fp);
RGBDATA ** data = readBmpDataToArr(fp);
closeBmpImage(fp);
data = flipMatrix(data,512);
FILE* fp_new = openBmpImage("new.bmp", "w");
saveMatrixToBmpFile(fileHead, infoHead, data, fp_new);
closeBmpImage(fp_new);
getchar();
return 0;
}
效果如下:
處理前
處理後:
這樣就完成了bmp文件的讀寫,實現倉促代碼中還有很多細節問題,比如只支持24位bits的圖像等等,以後有機會慢慢改吧。