bmp实现图像缩放

    bmp刷图是比较简单的,它需要注意的是bmp在windows系统下会自动生成54个字

节的头文件结构体信息,如果要在知道bmp图的图像尺寸的话,就可以用lseek函数直接跳过这54个字节直接读取自己想要的RGB图像数据,bmp图像不同的是它的图像读取顺序,是从左到右,从上到下,所以要刷到LCD屏幕中显示,需要进行颠倒图像数据。还有就是bmp图像RGB图像是3个字节即24位,但LCD一个像素点是4个字节,需要每3个字节刷到4个字节,跳过一个字节。

    因为在这次项目中,不是简单的把图刷进去,而是对不符合屏幕尺寸的图像可以自动识别并进行放大缩小来适应屏幕,所以事先是不知道图片的尺寸的,要利用bmp的头文件信息结构体知道该图像的长宽,所以就不能跳过这54个字节,而是跳过14的字节。以上是bmp图刷到LCD屏幕的所有注意事项,下面是实现代码。

#include "../inc/include.h"

typedef unsigned char  BYTE;
typedef unsigned short WORD;
typedef unsigned long  DWORD;
typedef long LONG;

typedef struct tagBITMAPINFOHEADER
{
	DWORD      biSize;
	LONG       biWidth;
	LONG       biHeight;
	WORD       biPlanes;
	WORD       biBitCount;
	DWORD      biCompression;
	DWORD      biSizeImage;
	LONG       biXPelsPerMeter;
	LONG       biYPelsPerMeter;
	DWORD      biClrUsed;
	DWORD      biClrImportant;
} BITMAPINFOHEADER;

int show_bmp(char *name) //显示bmp图片
{
	BITMAPINFOHEADER info_head;
	unsigned char *bmp_buf;

	int fd_bmp = open(name, O_RDWR);
	if (fd_bmp < 0)
	{
		perror("bmp open fail");
		return -1;
	}

	//跳过14个字节的头文件信息,直接读取BITMAPINFOHEADER结构体
	lseek(fd_bmp, 14, SEEK_SET);
	read(fd_bmp, &info_head, sizeof(BITMAPINFOHEADER));

	if ((info_head.biHeight != 480) || (info_head.biWidth != 800))
	{
		printf("This bmp_image is (%d*%d),I have changed it to 800*480.\n", info_head.biWidth, info_head.biHeight);
	}

	unsigned char bmp_prebuf[info_head.biWidth * info_head.biHeight *3];
	read(fd_bmp, bmp_prebuf, sizeof(bmp_prebuf));
	close(fd_bmp);

	//用最邻近插值来实现图像的变换
	bmp_buf = insert_near(bmp_prebuf, info_head.biWidth, info_head.biHeight, 800, 480);

	bzero(lcd, LCD_SIZE);
	usleep(1000);

	/*由于bmp图片只有三个字节数据,而且刷图顺序是从下往上,要进行数据转换*/
	for (int line = 0; line < 480; ++line)
	{
		for (int pixel = 0; pixel < 800; ++pixel)
		{
			int s = (line*800 + pixel) * 3;
			pre_lcd[479-line][pixel] = (bmp_buf[s+0]) | (bmp_buf[s+1]<<8) | (bmp_buf[s+2]<<16);
		}
	}

	return 0;
}

 

你可能感兴趣的:(专业)