增加一套缓冲区,在位图上画彩条和灰阶

在昨天写的程序的基础上增加了一套缓冲区scr_R、scr_G、scr_B作为画布,画图前先在缓冲区里操作,然后再输出到文件,从而增加了灵活度和可画图形的复杂性。

难点在于内存的分配、释放,以及缓冲区指针的寻址。目前,程序对于下标越界没有做任何处理。

绘图函数有:dot、box、gray_bar、color_bar,其中dot是最基本的画点函数,因为box也是由一个一个的dot组成的。

gray_bar和color_bar是利用box函数完成的。

因为现在的机器很快,所以即使嵌套调用也没问题。

如果将三个颜色的缓冲区合并起来,可以通过单条fwrite语句直接写入文件,但是这样内存里保存图像的数据格式必须与输出的格式完全一致。如果定死了输出格式,那么问题不大。如果输出的图像是用来喂视频编码器的,那么可能就要定死格式,以进行优化。

代码如下。程序在C-Free 4.0,mingw2.95编译器下编译通过。

#include 
#include 

typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;

#pragma pack(2) 

#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
#define s8 int8_t
#define s16 int16_t
#define s32 int32_t

struct BM_Header
{
	u8  bfType[2];
	u32 bfSize;
	u16 bfReserved1;
	u16 bfReserved2;
	u32 bfOffBits;
};

struct BM_Info
{
	u32 biSize;
	s32 biWidth;
	s32 biHeight;
	u16 biPlanes;
	u16 biBitCount;
	u32 biCompression;
	u32 biSizeImage;
	s32 biXPelsPerMeter;
	s32 biYPelsPerMeter;
	u32 biClrUsed;
	u32 biClrImportant;
};

struct RGB_Pixel
{
	u8	B;
	u8	G;
	u8	R;
};

struct BM_Header BH;
struct BM_Info BI;
struct RGB_Pixel RGB;
int Width = 800;
int Height = 600;
int BitDepth = 24;
FILE* fp;
char* scr_R;
char* scr_G;
char* scr_B;

void init_BM_Header()
{
	BH.bfType[0] = 'B';
	BH.bfType[1] = 'M';
	BH.bfSize = Width * Height * (BitDepth / 8) + sizeof(BH) + sizeof(BI);
	BH.bfReserved1 = 0;
	BH.bfReserved2 = 0;
	BH.bfOffBits = sizeof(BH) + sizeof(BI);
}

void init_BM_Info()
{
	BI.biSize = sizeof(BI);
	BI.biWidth = Width;
	BI.biHeight = 0 - Height;
	BI.biPlanes = 1;
	BI.biBitCount = BitDepth;
	BI.biCompression = 0;
	BI.biSizeImage = Width * Height * (BitDepth / 8);
	BI.biXPelsPerMeter = 2834;
	BI.biYPelsPerMeter = 2834;
	BI.biClrUsed = 0;
	BI.biClrImportant = 0;	
}

int check(const char* name, int value, int normal)
{
	printf("%-14s == %-14d", name, value);
	if(value == normal)
	{
		printf("[OK]\n");
		return 1;
	}
	else
	{
		printf("[NG] (=> %d)\n", normal);
		printf("[STOP] Bad value of `%s`, abort.\n", name);
		exit(-1);
		return 0;
	}	
}

void show_types()
{
	check("sizeof(u8)", sizeof(u8), 1);
	check("sizeof(u16)", sizeof(u16), 2);
	check("sizeof(u32)", sizeof(u32), 4);
	check("sizeof(s32)", sizeof(s32), 4);
	check("sizeof(BH)", sizeof(BH), 14);
	check("sizeof(BI)", sizeof(BI), 40);
	check("sizeof(RGB)", sizeof(RGB), 3);
}

void dot(int x, int y, int R, int G, int B)
{
	scr_R[y*Width+x] = R;
	scr_G[y*Width+x] = G;
	scr_B[y*Width+x] = B;	
}

void box(int x1, int y1, int x2, int y2, int R, int G, int B)
{
	int i;
	int j;
	for(j=y1;j<=y2;j++)
	{
		for(i=x1;i<=x2;i++)
		{
			dot(i,j,R,G,B); 
		}
	}
}

void gray_bar(int x1,int y1,int x2,int y2,int step)
{
	int i;
	int len = x2-x1+1;
	for(i=0;i

运行结果是这样的:

你可能感兴趣的:(数字图像处理)