C语言bmp图片读取写入

一、介绍
bmp是我们常用的一种图片格式,这里用c语言写一个程序打开,读取像素点然后增亮
增亮公式 y = kx + b
这里用的24位的真彩bmp图片

二、实现

img_bmp.c

#include 
#include 

// bmp图片头大小 24位深度的 
#define BMP_HEADER_SIZE 54

void read_bmp (const char* filename, unsigned int** img_data, int *height, int *width) 
{
     
	FILE *fp;
	int i,j;
	
	printf("打开图片...\n");
	if ((fp=fopen(filename,"rb"))==NULL) 
	{
     
    	printf("打开bmp失败\n", filename);
    	exit(1);
	}
	printf("跳过18字节...\n");
	for (i=0; i<18; i++) fgetc(fp); 
	
	printf("读取宽度和高度...\n");
	fread(width, sizeof(int), 1, fp);
	fread(height, sizeof(int), 1, fp);
	if ((*height) < 0 || (*width) < 0) 
	{
     
	    printf("不支持该格式 高度 %d, 宽度 %d\n", (*height), (*width));
	    exit(1);
	}
	printf("读取图片大小宽度 %d  高度 %d \n", (*width), (*height));
  	*img_data = (unsigned int*) malloc((*width) * (*height) * sizeof(unsigned int));
	printf("跳过28字节...\n");
	for (i=0; i<28; i++) fgetc(fp);
	
	//每行必须有4的倍数 
	int padding = (4-(((*width)*3)&3))&3;
  	int idx=0;    
  	
	printf("读取像素点...\n");
  	for (i=0; i < (*height); ++i) 
	{
     
		for (j=0; j< (*width); ++j) 
		{
     
    		unsigned char b = fgetc(fp); //B
			unsigned char g = fgetc(fp); //G
      		unsigned char r = fgetc(fp); //R
      		(*img_data)[idx] = (((unsigned int ) r << 16) | ((unsigned int ) g << 8) | ((unsigned int ) b << 0));
      		idx++;
		}
	  	//丢掉多余字节 
	  	for (j=0; j< padding; ++j) 
		{
     
	  		unsigned char b = fgetc(fp);
	  	}
  	}
  	printf("读取完成...\n");
  	fclose(fp);
}


void write_bmp (const char* filename, unsigned int* img_data, int height, int width)
{
     
	FILE *fp;
	int i,j;
  	unsigned int file_size = width * height * 3 + BMP_HEADER_SIZE;
  	unsigned char header[BMP_HEADER_SIZE] = {
      0x42, 0x4d,         // BMP & DIB
                                        0x00, 0x00, 0x00, 0x00,// size of file in bytes
                                        0x00, 0x00, 0x00, 0x00, // reserved
                                        0x36, 0x00, 0x00, 0x00, // offset of start of image data
                                        0x28, 0x00, 0x00, 0x00, // size of the DIB header
                                        0x00, 0x00, 0x00, 0x00,// width in pixels
                                        0x00, 0x00, 0x00, 0x00,// height in pixels
                                        0x01, 0x00, // number of color planes
                                        0x18, 0x00, // number of bits per pixel
                                        0x00, 0x00, 0x00, 0x00, // no compression - BI_RGB
                                        0x00, 0x00, 0x00, 0x00, // image size - dummy 0 for BI_RGB
                                        0x13, 0x0b, 0x00, 0x00, // horizontal ppm
                                        0x13, 0x0b, 0x00, 0x00, // vertical ppm
                                        0x00, 0x00, 0x00, 0x00, // default 2^n colors in palatte
                                        0x00, 0x00, 0x00, 0x00  // every color is important
                                      };
    #if 1
    header[2] = (file_size & 0xff);
	header[3] = ((file_size >> 8) & 0xff);
	header[4] = ((file_size >> 16) & 0xff);
	header[5] = ((file_size >> 24) & 0xff);
	header[18] = (width & 0xff); 
	header[19] = ((width >> 8) & 0xff);
	header[20] = ((width >> 16) & 0xff);
	header[21] = ((width >> 24) & 0xff);
	header[22] = (height & 0xff);
	header[23] =  ((height >> 8) & 0xff);
	header[24] = ((height >> 16) & 0xff);
	header[25] = ((height >> 24) & 0xff);
	#endif
	printf("写入图片大小宽度 %d  高度 %d \n", width, height);
    if ((fp=fopen(filename,"wb"))==NULL) 
	{
      
    	printf("打开 %s文件失败\n", filename); 
    	exit(1);
  	}
  	//写头 
  	fwrite(header, 1, BMP_HEADER_SIZE, fp);
  	//写像素点 
  	int padding = (4-((width*3)&3))&3;
  	int idx = 0;
  	for (i = 0; i <  height; ++i) 
	{
     
    	unsigned char p[3];
    	for (j = 0; j < width ; ++j) 
		{
     
      		//写像素点 
      		p[0] = (img_data[idx] >>  0) & 0xff; //B
      		p[1] = (img_data[idx] >>  8) & 0xff; //G
      		p[2] = (img_data[idx] >> 16) & 0xff; //R
      		idx++;
      		fwrite(p, 1, 3, fp);
    	}
    	//写入多余字节 
    	if (padding) 
		{
     
    		p[0]=p[1]=p[2]=0;
    		fwrite(p,1,padding,fp);
    	}
  	}
  	fclose(fp);
}

img_bmp.h

#ifndef __IMG_BMP_H
#define __IMG_BMP_H

void read_bmp (const char* filename, unsigned int** img_data, int *height, int *width);
void write_bmp (const char* filename, unsigned int* img_data, int height, int width);

#endif

main.c

#include 
#include 

int bmp_test()
{
     
	unsigned int *img,*img1,tmp1;
	int rows,cols,i,j;
	unsigned char *tmp;
	const int k = 1,b = 150;//k对比度 b亮度 
	
	printf("读取图片...\n");
	read_bmp("test3.bmp", &img, &rows, &cols);
	img1 = img;
	printf("读取成功\n"); 
	for(i = 0; i < rows; i++)
		for(j = 0; j < cols; j++)
		{
     
			tmp = (unsigned char *)img;
			tmp1 = tmp[0]*k + b;
			tmp1 = tmp1 > 254 ? 255 : tmp1;
			tmp[0] = tmp1;
			tmp1 = tmp[1]*k + b;
			tmp1 = tmp1 > 254 ? 255 : tmp1;
			tmp[1] = tmp1;
			tmp1 = tmp[2]*k + b;
			tmp1 = tmp1 > 254 ? 255 : tmp1;
			tmp[2] = tmp1;
			img++;
		}
	printf("增亮完成\n"); 
  	write_bmp("out.bmp", img1, rows, cols);
  	printf("写入成功\n"); 
}

int main(int argc, char *argv[]) {
     
	bmp_test();
	printf("图像增亮图片生成\n out.bmp"); 
	return 0;
}

效果:

你可能感兴趣的:(C语言,图像处理,bmp,c语言,图像处理)