一、介绍
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;
}
效果: