BMP格式图像的反色和变为灰度图代码

#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <math.h>
#include <stdlib.h>

int InvertImage(char *srcImage, char *destIMage, int iFlag)
{
	BITMAPFILEHEADER bmfHeader;
	BITMAPINFOHEADER bmiHeader;
	int i;
	
	FILE *pFile;
	if ((pFile = fopen(srcImage, "rb")) == NULL)
	{
		printf("open bmp file error.");
		exit(-1);
	}
	
	//读取文件和Bitmap头信息
	fseek(pFile,0,SEEK_SET);
	fread(&bmfHeader,sizeof(BITMAPFILEHEADER),1,pFile);
	fread(&bmiHeader,sizeof(BITMAPINFOHEADER),1,pFile);
	
	//先不支持小于16位的位图
	int bitCount = bmiHeader.biBitCount;
	if (bitCount < 16)
	{        
		printf("Image format is error!");
		exit(-1);
	}
	
	int srcW = bmiHeader.biWidth;//宽度,多少像素点
    int srcH = bmiHeader.biHeight;//高度
	
	int lineSize = bitCount * srcW / 8;
    //偏移量,windows系统要求每个扫描行按四字节对齐
	//int alignBytes = ((bmiHeader.biWidth * bitCount + 31) & ~31) / 8L
		//- bmiHeader.biWidth * bitCount / 8L;
	int srcLine = ((srcW * bitCount + 31) / 32) * 4;
	//int srcBufLine = srcLine * srcH;
	
	int srcBufSize = srcLine * srcH;
	
	BYTE *srcBuf = (BYTE *)malloc(srcBufSize);
	if(!srcBuf){
		printf("Malloc memory fail!");
		exit(-1);
	}

	for(i = 0; i < srcH; i++){
		fread(&srcBuf[i * srcLine], srcLine, 1, pFile);
		//fseek(pFile, alignBytes, SEEK_CUR);
	}

	//iFlag equal 1 表示灰度
	if(iFlag){
		for(i = 0; i < srcH; i++){
			for(int j = 0; j < srcW; j++){
				int k = (srcBuf[i * srcLine + j * bitCount / 8 + 0] + 
					srcBuf[i * srcLine + j * bitCount / 8 + 1] + 
					srcBuf[i * srcLine + j * bitCount / 8 + 2] ) / 3;
				
				srcBuf[i * srcLine + j * bitCount / 8 + 0] = k;
				srcBuf[i * srcLine + j * bitCount / 8 + 1] = k;
				srcBuf[i * srcLine + j * bitCount / 8 + 2] = k;
			}
		}
	}else{//反色
		for(i = 0; i < srcH; i++){
			for(int j = 0; j < srcW; j++){
				for(int k = 0; k < 3; k++){
					srcBuf[i * srcLine + j * bitCount / 8 + k] = 
						abs(srcBuf[i * srcLine + j * bitCount / 8 + k] - 255);
				}
			}
		}
	}
	

	HFILE hfile = _lcreat(destIMage, 0);
	
	//写入文件头信息
	_lwrite(hfile,(LPCSTR)&bmfHeader,sizeof(BITMAPFILEHEADER));
	//写入Bitmap头信息
	_lwrite(hfile,(LPCSTR)&bmiHeader,sizeof(BITMAPINFOHEADER));
	//写入图像数据
	_lwrite(hfile,(LPCSTR)srcBuf, srcBufSize);
    _lclose(hfile);
	fclose(pFile);
	free(srcBuf);

	return 0;
}

int main(int argc, char* argv[])
{
	InvertImage("0.bmp", "image反色.bmp", 0);
	InvertImage("0.bmp", "image灰度.bmp", 1);
	//system("pause");
	return 0;
}
<pre name="code" class="cpp">代码如果想在linux下运行,更改几个头文件,并且自己加上bmp格式头部的结构体,最后的写入文件该给库里面的IO就可以了
点赞