C语言 NOTE17

===================================================

BMP图片编写规范代码整理:

创建文件夹bin,pic,src,inc,其中bin存放二进制执行文件,pic存放bmp图片,src存放源文件,inc存放头文件,编写makefile

makefile:

TARGET 			=./bin/lcdimage
SRC 			=$(wildcard ./src/*.c)
OBJ				=$(patsubst %.c, %.o, $(SRC))
CC 				=arm-linux-gcc
CONFIG 			=-I./inc 

$(TARGET):$(OBJ)
	$(CC) $^ -o $@ $(CONFIG) -g
%.o:%.c
	$(CC) $< -c -o $@ $(CONFIG) 

clean:
	rm $(TARGET) $(OBJ)

/inc/bmp.h:

/********************************************************************
  > File Name: bmp.h
  > Author: xiening
  > Mail:  [email protected]  
  > Created Time: 2019年11月24日 星期日 09时58分34秒
 *******************************************************************/

#ifndef _BMP_H 
#define _BMP_H


#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

//BMP文件头部:(14位)
typedef struct BITMAPFILEHEADER{
	short bfType;
	unsigned bfSize;
    short bfReserved1;
	short bfReserved2;
	unsigned bfOffBits;	
}BitMapFileHeader;

//BMP文件信息:(40位)
typedef struct BITMAPINFOHEADER{
	unsigned biSize;
	unsigned biWidth;
	unsigned biHeigh;
	short biPlanes;
	short biBitCount;
	unsigned biCompression;
	unsigned biSizeTmage;
	int biXpelsPerMeter;
	int biYpelsPerMeter;
	unsigned biClrUsed;	
	unsigned biClrImportant;
}BitMapInfoHeader;

//bmp图片简单信息:
typedef struct BMPSIMPLEINFO{
	unsigned Width;
	unsigned Heigh;
	short Count;
	unsigned *Bmp; //用户存放位图数据
}BmpSimpleInfo;

//读取bmp图片信息至结构体BmpSimpleInfo
BmpSimpleInfo* ReadBmpInfo(const char *filename);

//显示bmp图片
void ShowBmp(char *filedev, BmpSimpleInfo *tem);

//bmp图片大小转换
BmpSimpleInfo* ZoomBmpSize(int WidthScale, 
					int HeighScale, BmpSimpleInfo *tem);

//销毁bmp图片:
void DestoryBmp(BmpSimpleInfo *tem);


#endif


/src/bmp.c:

/********************************************************************
  > File Name: bmp.c
  > Author: xiening
  > Mail:  [email protected]  
  > Created Time: 2019年11月24日 星期日 10时40分53秒
 *******************************************************************/

#include "bmp.h"

//读取bmp图片信息至结构体BmpSimpleInfo
BmpSimpleInfo* ReadBmpInfo(const char *filename)
{
	//打开文件
	FILE *fp = fopen(filename, "r+");
	if(NULL == fp)
	{
		perror("fopen error\n");
		return NULL;
	}

	//读BMP文件头部
	BitMapFileHeader bmpheader;
	int ret = fread(&bmpheader, 1, 14, fp);
	if(14 != ret)
	{
		perror("fread error\n");
		return NULL;
	}
	BitMapInfoHeader bmpinfo;
	ret = fread(&bmpinfo, 1, 40, fp);
	if(40 != ret)
	{
		perror("fread error\n");
		return NULL;
	}
	
    //返回简单bmp信息
	unsigned BmpSize = bmpinfo.biWidth*bmpinfo.biHeigh
							*bmpinfo.biBitCount/8;
	BmpSimpleInfo *tem = malloc(sizeof(BmpSimpleInfo));
	tem->Width = bmpinfo.biWidth;
	tem->Heigh = bmpinfo.biHeigh;
	tem->Count = bmpinfo.biBitCount/8;
	tem->Bmp = malloc(tem->Width*tem->Heigh*4);
	char buf[BmpSize];
	ret = fread(buf, 1, BmpSize, fp);
	if(BmpSize != ret)
	{
		perror("fread error\n");
	}
	if(3 == tem->Count)
	{
		
		for(int i=0; i<tem->Heigh; i++)
		{
			for(int j=0; j<tem->Width; j++)
			{
				tem->Bmp[(tem->Heigh-1-i)*tem->Width+j] 
								= buf[(i*tem->Width+j)*3]
								| buf[(i*tem->Width+j)*3+1] << 8
								| buf[(i*tem->Width+j)*3+2] << 16;
			}
		}
	}
	if(4 == tem->Count)
	{
		for(int i=0; i<tem->Heigh; i++)
		{
			for(int j=0; j<tem->Width; j++)
			{
				tem->Bmp[(tem->Heigh-1-i)*tem->Width+j] 
					= (unsigned)buf[i*tem->Width+j];
			}
		}
	}

	return tem;


}

//显示bmp图片:
void ShowBmp(char *filedev, BmpSimpleInfo *tem)
{
	//打开文件
	FILE *fp = fopen(filedev, "r+");
	if(NULL == fp)
	{
		perror("fopen error\n");
		return;
	}
	int fd = fileno(fp);
	//内存映射:
	unsigned *buf = mmap(NULL, 480*800*4, 
							PROT_READ|PROT_WRITE,
							MAP_SHARED, fd, 0);

	memcpy(buf, tem->Bmp, 480*800*4);

	//解除映射
	munmap(buf, 480*800*4);
	fclose(fp);
	fp = NULL;

}

//bmp图片大小转换
BmpSimpleInfo* ZoomBmpSize(int WidthScale, 
							int HeighScale, BmpSimpleInfo *tem)
{
	//赋值新信息
	BmpSimpleInfo *tmp = malloc(sizeof(BmpSimpleInfo));
	tmp->Width = WidthScale;
	tmp->Heigh = HeighScale;
	tmp->Count = tem->Count;
	int BmpSize = WidthScale*HeighScale*4;
	tmp->Bmp = malloc(BmpSize);
	printf("tem:%d-%d-%d\n", tem->Width, tem->Heigh, tem->Count);
	printf("tmp:%d-%d-%d\n", tmp->Width, tmp->Heigh, tmp->Count);

	int wsc = tem->Width/(double)WidthScale*100;
	int hsc = tem->Heigh/(double)HeighScale*100;
	for(int i=0; i<HeighScale; i++)
	{
		for(int j=0; j<WidthScale; j++)
		{
			
			double number = (j*wsc)/100+tem->Width*((i*hsc)/100);
			unsigned long num = j*tem->Heigh/WidthScale+i*tem->Width*tem->Heigh/HeighScale;
			tmp->Bmp[i*WidthScale+j] = tem->Bmp[(int)number];
		}
	}
	return tmp;
}

//销毁bmp图片:
void DestoryBmp(BmpSimpleInfo *tem)
{
	free(tem->Bmp);
	free(tem);
	tem = NULL;
}

/src/1.LCD封装.c

/********************************************************************
  > File Name: 1.LCD封装.c
  > Author: xiening
  > Mail:  [email protected]  
  > Created Time: 2019年11月22日 星期五 14时31分11秒
 *******************************************************************/

#include "bmp.h"

int main(int argc, char const *argv[])
{
	if(2 != argc)
	{
		perror("use:./lcdimage filename\n");
		return -1;
	}
	//读取图片信息
	BmpSimpleInfo *tem = ReadBmpInfo(argv[1]);
	
	//bmp图片大小转换:
	BmpSimpleInfo *tmp = ZoomBmpSize(800, 480, tem);
	
	//显示bmp图片
	ShowBmp("/dev/fb0", tmp);

	//销毁图片
	DestoryBmp(tmp);
	DestoryBmp(tem);
	
    return 0 ;
}

发布了52 篇原创文章 · 获赞 2 · 访问量 2017

猜你喜欢

转载自blog.csdn.net/weixin_42191545/article/details/103241475
今日推荐