天天看點

基于gec6818開發闆的LCD上bmp圖檔顯示

方法一

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

/*在LCD上顯示800*480像素點的bmp圖檔*/
int show_bmp(const char *bmp_name)
{
	//1,将圖檔的像素點資訊讀取出來
		//1)打開圖檔 --> bmp_name		open
		int bmp_fd = open("bmp_name", O_RDWR);
		if (-1 == bmp_fd)
		{
			perror("open bmp failed");
			return -1;
		}
		//2)讀取圖檔像素點内容 -->跳過檔案開頭的54位元組頭資訊 read
		char buf[800*480*3];			//存放讀取的bmp圖檔内容
		lseek(bmp_fd, 54, SEEK_SET);	//跳過前54位元組
		read(bmp_fd, buf, sizeof(buf));	//讀取像素點資訊
///BGR --> ARGB//
		unsigned int bmp_buf[800*480];	//800*480*4位元組  轉換之後的ARGB資料
		unsigned char A, R, G, B;	//存放圖檔像素點的A R G B資料
		int i, j;
		unsigned int tmp;
		for (i = 0; i < 800*480; ++i)
		{
			A = 0x00;	//透明度
			B = buf[3*i];		//藍色
			G = buf[3*i + 1];	//綠色
			R = buf[3*i + 2];	//紅色
			// A  R  G  B ==> ARGB   1234 = 1*1000 + 2*100 + 3*10 + 4
			// A << 24   R<< 16  G << 8  B
			bmp_buf[i] = A<<24 | R<<16 | G<<8 | B;
 		}
///圖檔資料實作翻轉///
 		for (i = 0; i < 480; ++i)
 		{
 			for (j = 0; j < 800; ++j)
 			{
 				//把第i行,第j列的像素點跟 第479-i行,第j列的像素點進行交換
 				tmp = bmp_buf[800*i+j];
 				bmp_buf[800*i+j] = bmp_buf[800*(479-i)+j];
 				bmp_buf[800*(479-i)+j] = tmp;	
 			}	
 		}
//
	//2,将讀取的圖檔像素點資料寫入到LCD
		//1)打開LCD檔案  --> /dev/fb0	open
		int lcd_fd = open("/dev/fb0", O_RDWR);
		if (-1 == lcd_fd)
		{
			perror("open lcd failed ");
			return -1;
		}
		//2)把 RGB-> ARGB之後的像素點内容寫入到LCD	  write
		write(lcd_fd, bmp_buf, sizeof(bmp_buf));

	//3,關閉圖檔檔案,關閉LCD檔案	close
	close(bmp_fd);
	close(lcd_fd);

	return 0;
}

int main(int argc, char const *argv[])
{
	if (argc != 2)
	{
		printf("請按照格式輸入指令:%s <filename>\n",argv[0]);
		return -1;
	}

	show_bmp(argv[1]);
	return 0;
}
           

方法二

記憶體映射顯示

#include <stdio.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

/*********************************************************
**		@函數名 	Show_Bmp
**		@函數功能	在LCD上顯示800*480像素點的bmp圖檔
**		@函數參數	pic_name:需要顯示的圖檔名
**		@傳回值		成功傳回0; 失敗傳回-1
**		@說明		無
*********************************************************/
int Show_Bmp(char *pic_name)
{
	//1,打開LCD,打開bmp
	int lcd_fd = open("/dev/fb0", O_RDWR);
	if (lcd_fd == -1)
	{
		perror("open lcd failed ");
		return -1;
	}
	//2,讀取圖檔像素點資料,并且進行解碼
	int bmp_fd = open(pic_name, O_RDWR);
	if (bmp_fd == -1)
	{
		perror("open bmp failed");
		return -1;
	}
	char buf[800*480*3];			//存放讀取的bmp圖檔内容
	lseek(bmp_fd, 54, SEEK_SET);	//跳過前54位元組
	read(bmp_fd, buf, sizeof(buf));	//讀取像素點資訊
	unsigned int bmp_buf[800*480];	//800*480*4位元組  轉換之後的ARGB資料
	unsigned char A, R, G, B;	//存放圖檔像素點的A R G B資料
	int i, j;
	unsigned int tmp;
	for (i = 0; i < 800*480; ++i)
	{
		A = 0x00;	//透明度
		B = buf[3*i];		//藍色
		G = buf[3*i + 1];	//綠色
		R = buf[3*i + 2];	//紅色
		// A  R  G  B ==> ARGB   1234 = 1*1000 + 2*100 + 3*10 + 4
		// A << 24   R<< 16  G << 8  B
		bmp_buf[i] = A<<24 | R<<16 | G<<8 | B;
	}
	for (i = 0; i < 240; ++i)
	{
		for (j = 0; j < 800; ++j)
		{
			//把第i行,第j列的像素點跟 第479-i行,第j列的像素點進行交換
			tmp = bmp_buf[800*i+j];
			bmp_buf[800*i+j] = bmp_buf[800*(479-i)+j];
			bmp_buf[800*(479-i)+j] = tmp;	
		}	
	}
	
	//3,将LCD映射到記憶體空間
	unsigned int *lcdmap = mmap(NULL, 800*480*4, PROT_READ | PROT_WRITE,  MAP_SHARED, lcd_fd, 0);
	if(lcdmap == MAP_FAILED)
	{
		perror("mmap failed");
		return -1;
	}
	
	//4,将解碼的圖檔資料寫入到LCD  bmp_buf[800*480] ==> lcdmap
 	for(i=0; i<800*480; i++)
	{
		lcdmap[i] = bmp_buf[i];
	} 
	/*//從上到下動态顯示圖檔
	for(i=0; i<480; i++)
	{
		for(j=0; j<800; j++)
		{
			lcdmap[800*i+j] = bmp_buf[800*i+j];
		}
		//每顯示一行資料,就延時1ms
		usleep(1*1000);		//延時1ms  其中1表示1微秒 
	} */
	//5,解除LCD映射,關閉檔案
	munmap(lcdmap, 800*480*4);
	close(lcd_fd);
	close(bmp_fd);
	return 0;
}


int main(int argc, char const *argv[])
{
	if (argc != 2)
	{
		printf("請按照格式輸入指令:%s <filename>\n",argv[0]);
		return -1;
	}

	Show_Bmp(argv[1]);
	return 0;
}








           

繼續閱讀