最近写了个bmp图像读取,将图片转化为单一颜色的小程序,直接上代码,仅供参考。
1.先上测试函数(基本一看就知道流程)
/**********************************************************************************************
Author: Lihaowei
Date: 2015-04-2
version:0.0
Discriptions:
1.This file is used to test "bitMapfunction.c" (load a bitmap,convert bitmap to single-color
image (R||G||B),and write a new bitmap).
************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "../include/bitMap.h"
void main()
{
char filename_in[20] = "input.bmp";
char filename_out1[20] = "output_r.bmp";
char filename_out2[20] = "output_g.bmp";
char filename_out3[20] = "output_b.bmp";
BITMAPFILE* bitmap1,*bitmap2,*bitmap3;
bitmap1 = loadBitmap(filename_in);
bitmap2 = loadBitmap(filename_in);
bitmap3 = loadBitmap(filename_in);
toSingleColor(bitmap1,'R');
toSingleColor(bitmap2,'G');
toSingleColor(bitmap3,'B');
writeBmp(filename_out1,bitmap1);
writeBmp(filename_out2,bitmap2);
writeBmp(filename_out3,bitmap3);
free(bitmap1);
free(bitmap2);
free(bitmap3);
}
2.头文件
/***********************************bitMap.h***********************************************************
Author: Lihaowei
Date: 2015-04-2
version:0.0
Discriptions:
************************************************************************************************/
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#pragma pack(1)
/*bitmap file header,size:14 bytes*/
typedef struct tagBITMAPFILEHEADER
{
u16 bfType;
u32 bfSize;
u16 bfReserved1;
u16 bfReserved2;
u32 bfOffBits;
}BITMAPFILEHEADER;
/*bitmap information header,size:40 bytes*/
typedef struct tagBITMAPINFOHEADER
{
u32 biSize;
u32 biWidth;
u32 biHeight;
u16 biPlanes;
u16 biBitCount;
u32 biCompression;
u32 biSizeImage;
u32 biXPelsPerMeter;
u32 biYPelsPerMeter;
u32 biClrUsed;
u32 biClrImportant;
}BITMAPINFOHEADER;
/*color palette,size:4 bytes*/
typedef struct tagRGBQUAD
{
u8 rgbBlue;
u8 rgbGreen;
u8 rgbRed;
u8 rgbReserved;
}RGBQUAD;
typedef struct tagBITMAP
{
BITMAPFILEHEADER bfHeader;
BITMAPINFOHEADER biHeader;
RGBQUAD bmpColors[1];
u8* imageData;
u8* dataR;
u8* dataG;
u8* dataB;
}BITMAPFILE;
BITMAPFILE * loadBitmap(char *path);
void writeBmp(char *path ,BITMAPFILE *bitmap);
void toSingleColor(BITMAPFILE *bitmap,char color);//color='R'||'G'||'B'
2.功能源文件
/************************************bitMapfunction.c**********************************************************
Author: Lihaowei
Date: 2015-04-2
version:0.0
Discriptions:
1.This file offer some functions to load a bitmap,convert bitmap to single-color
image (R||G||B),and to write a new bitmap.
2.To use these function , please include "bitMap.h" in your program
************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "../include/bitMap.h"
/*fuction:void toSingleColor(BITMAPFILE *bitmap,char color); */
/*convert to single-color image*/
/***********************************************************************************************/
void toSingleColor(BITMAPFILE *bitmap,char color)
{
int i,j;
int colorid=0;
switch(color)
{
case 'R': colorid = 0;
break;
case 'G': colorid = 2;
break;
case 'B': colorid = 1;
break;
default: colorid = 1;
}
for(i =0; i < bitmap->biHeader.biHeight; i++)
{
for(j = 0; j < bitmap->biHeader.biWidth; j++)
{
*(bitmap->imageData+3*((bitmap->biHeader.biWidth)*i+j)+colorid) = 0;
*(bitmap->imageData+3*((bitmap->biHeader.biWidth)*i+j)+(colorid+1)%3) = 0;
/*if(*(bitmap->imageData+3*((bitmap->biHeader.biWidth)*i+j)+(colorid+2)%3) > 50)
(bitmap->imageData+3*((bitmap->biHeader.biWidth)*i+j)+(colorid+2)%3) = 255;
else
(bitmap->imageData+3*((bitmap->biHeader.biWidth)*i+j)+(colorid+2)%3) = 0; */
}
}
}
/***********************************************************************************************/
/*fuction:BITMAPFILE * loadBitmap(char *path); */
/*load a bitmap*/
/***********************************************************************************************/
BITMAPFILE * loadBitmap(char *path)
{
int i,j;
BITMAPFILE * bitmap={0};
FILE *bmfp=fopen(path,"r+");
if( !bmfp )
{
printf("open %s error!\n",path);
exit(0);
}
bitmap = (BITMAPFILE*)malloc(sizeof(BITMAPFILE));
/********************************test the file to judge whether it is a bitmap**************************/
unsigned short bfType = 0;
fseek(bmfp, 0L, SEEK_SET);
fread(&bfType, sizeof(char), 2, bmfp);
if (0x4D42!= bfType)
{
printf("This is not a bmp file!!!\n");
exit(1);
}
/*******************************************************************************************************/
/*********************************read the Header of the bitmap*****************************************/
/*read file information header*/
fseek(bmfp, 0L, SEEK_SET);
fread(&(bitmap->bfHeader), sizeof(unsigned char), sizeof(BITMAPFILEHEADER), bmfp);
/*read bmp information header*/
fread(&(bitmap->biHeader), 1 ,sizeof(BITMAPINFOHEADER), bmfp);
/*read RGBQUAD information*/
/******************************************************************************************************/
/********************************read image data*******************************************************/
/*read image data*/
if(bitmap->biHeader.biBitCount == 24)
{
unsigned int width = bitmap->biHeader.biWidth;
unsigned int height = bitmap->biHeader.biHeight;
bitmap->imageData = (unsigned char*)malloc(sizeof(unsigned char)*width*3*height);
bitmap->dataR = (unsigned char*)malloc(sizeof(unsigned char)*width * height);
bitmap->dataG = (unsigned char*)malloc(sizeof(unsigned char)*width * height);
bitmap->dataB = (unsigned char*)malloc(sizeof(unsigned char)*width * height);
fseek(bmfp,bitmap->bfHeader.bfOffBits,SEEK_SET);
/*read imageData */
fread(bitmap->imageData, sizeof(unsigned char), width*3*height, bmfp);
for(i =0; i < bitmap->biHeader.biHeight; i++)
{
for(j = 0; j <bitmap->biHeader.biWidth; j++)
{
/*seperate R G B data from imageData */
*(bitmap->dataB+(bitmap->biHeader.biHeight-i-1)*(bitmap->biHeader.biWidth)+j) =
*(bitmap->imageData+3*((bitmap->biHeader.biWidth)*i+j));
*(bitmap->dataG+(bitmap->biHeader.biHeight-i-1)*(bitmap->biHeader.biWidth)+j) =
*(bitmap->imageData+3*((bitmap->biHeader.biWidth)*i+j)+1);
*(bitmap->dataR+(bitmap->biHeader.biHeight-i-1)*(bitmap->biHeader.biWidth)+j) =
*(bitmap->imageData+3*((bitmap->biHeader.biWidth)*i+j)+2);
}
}
}
else
{
printf("Only handle 24bit per pixel bitMap\n");
exit(0);
}
/******************************************************************************************************/
/****************************write to dat file*********************************************************/
/*write to dat file*/
FILE* fpDataBmp1,*fpDataBmp2,*fpDataBmp3;
/* New a file to save the data matrix */
if((fpDataBmp1 = fopen("data_R.dat","w+")) == NULL)
{
printf("Failed to construct file bmpData_R.dat!");
exit(1);
}
if((fpDataBmp2 = fopen("data_G.dat","w+")) == NULL)
{
printf("Failed to construct file bmpData_R.dat!");
exit(1);
}
if((fpDataBmp3 = fopen("data_B.dat","w+")) == NULL)
{
printf("Failed to construct file bmpData_R.dat!");
exit(1);
}
for(i =0; i < bitmap->biHeader.biHeight; i++)
{
fprintf(fpDataBmp1,"line %d :\n",i);
fprintf(fpDataBmp2,"line %d :\n",i);
fprintf(fpDataBmp3,"line %d :\n",i);
for(j = 0; j < bitmap->biHeader.biWidth; j++)
{
fprintf(fpDataBmp1, "%-3d ", *(bitmap->dataR+(bitmap->biHeader.biHeight-i-1)*(bitmap->biHeader.biWidth)+j));
fprintf(fpDataBmp2, "%-3d ", *(bitmap->dataG+(bitmap->biHeader.biHeight-i-1)*(bitmap->biHeader.biWidth)+j));
fprintf(fpDataBmp3, "%-3d ", *(bitmap->dataB+(bitmap->biHeader.biHeight-i-1)*(bitmap->biHeader.biWidth)+j));
if ((j+1)%32 == 0)
{
fprintf(fpDataBmp1, "\n");
fprintf(fpDataBmp2, "\n");
fprintf(fpDataBmp3, "\n");
}
}
}
fclose(fpDataBmp1);
fclose(fpDataBmp2);
fclose(fpDataBmp3);
fclose(bmfp);
return bitmap;
}
/***********************************************************************************************/
/*fuction:void writeBmp(char *path ,BITMAPFILE *bitmap); */
/*write a new bitmap*/
/***********************************************************************************************/
void writeBmp(char *path ,BITMAPFILE *bitmap)
{
unsigned int width = bitmap->biHeader.biWidth;
unsigned int height = bitmap->biHeader.biHeight;
FILE *bmfp=fopen(path,"w+");
if(bmfp == NULL)
{
printf("fopen %s failed !\n",path);
exit(1);
}
/***************************write image header****************************************/
/*write file information header*/
fseek(bmfp, 0L, SEEK_SET);
fwrite(&(bitmap->bfHeader),sizeof(unsigned char), sizeof(BITMAPFILEHEADER), bmfp);
/*write bmp information header*/
fwrite(&(bitmap->biHeader), 1 ,sizeof(BITMAPINFOHEADER), bmfp);
/*write RGBQUAD information*/
/**************************************************************************************/
/*write data*/
fseek(bmfp, bitmap->bfHeader.bfOffBits, SEEK_SET);
fwrite(bitmap->imageData,sizeof(unsigned char),width*3*height,bmfp);
}
/***********************************************************************************************/
一些原理性的细节之后再写博客补充吧。而且这个程序在数据对齐方面没注意,只支持24位真彩色图的处理。