精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux應用開發(fā)-LCD顯示BMP圖片

DS小龍哥-嵌入式技術 ? 來源:DS小龍哥-嵌入式技術 ? 作者:DS小龍哥-嵌入式技 ? 2022-08-14 09:18 ? 次閱讀

1. 前言

BMP是一種與硬件設備無關的圖像文件格式,是Windows環(huán)境中交換與圖有關的數(shù)據(jù)的一種標準,在Windows環(huán)境中運行的圖形圖像軟件都支持BMP圖像格式。BMP格式的圖片存放的就是原始的RGB數(shù)據(jù),一般沒有做壓縮,也就是圖片的畫質是最原始的,也導致BMP圖片占用的內存非常大。現(xiàn)在常用的jpg、jpeg格式都是壓縮格式,保存的時候通過算法編碼壓縮,顯示的時候再解壓成RGB數(shù)據(jù)渲染顯示。

BMP格式在嵌入式設備里用的還是較多的,BMP雖然占用內存大,優(yōu)點是顯示速度快,因為不需要解碼,在性能一般,不是很強的設備上使用BMP顯示效率較高。

為了解BMP格式,這篇文章就采用Linux開發(fā)板作為實驗平臺,在LCD屏上讀取BMP圖片,完成繪制,不需要借助任何第三方庫,全部由純C語言代碼一行一行敲出來,深入理解Linux下幀緩沖編程框架、BMP圖片的存儲結構原理。

一般BMP圖片由以下4個部分組成: 1:文件頭 2:圖像參數(shù) 3:調色板 4:位圖數(shù)據(jù)

現(xiàn)在一般采用的圖片都是RGB888,24位真彩色,就沒有調色板,只有3個部分組成。

其中文件頭存放圖片的屬性,位圖數(shù)據(jù)偏移量。圖像參數(shù)存放圖片的寬高、像素位數(shù)等信息。位圖數(shù)據(jù)就是存儲的原始RGB數(shù)據(jù),可以直接在LCD屏上顯示。

下面列出BMP圖片的結構:

image-20220124001914847image-20220124001941914

位圖數(shù)據(jù)存儲規(guī)則:

(1)每行的字節(jié)數(shù)必須是4的倍數(shù),如果不是,則需要用0補齊。 (2)BMP位圖數(shù)據(jù)的存放是從下到上,從左到右的。先讀最后一行,讀完后在讀倒數(shù)第二行。

image-20220124002345869

按照上面的介紹,就可以定義一個BMP解碼專用的結構體,對應文件里每個字節(jié)數(shù)據(jù),結構體成員變量必須按照上面截圖里的說明定義。整個結構體還需要進行強制1個字節(jié)對齊,不然每個編譯器對結構體的空間開辟規(guī)則有差異,會導致數(shù)據(jù)錯位。

#pragma pack(1) //強制1個字節(jié)對齊
//BMP的文件頭
struct _BMP_HEAD
{
    char type[2]; //圖片的類型 "BM"
    unsigned int size; //文件大小
    unsigned short  r1; //保留1
    unsigned short  r2; //保留2
    unsigned int seek; //數(shù)據(jù)偏移字節(jié)(真實像素點數(shù)據(jù))
};

//BMP的參數(shù)信息
struct _BMP_INFO
{
    unsigned int size; //當前結構體大小
    unsigned int w; //寬度
    unsigned int h; //高度
    unsigned short flag; //固定為1
    unsigned short bit; //像素點的位數(shù)
    unsigned int r1; //壓縮方式  0
    unsigned int r2; //水平分辨率
    unsigned int r3; //垂直分辨率
    unsigned int r4; //垂直分辨率
    unsigned int r5; //引用色彩
    unsigned int r6; //關鍵色彩
};
復制代碼

2. 實現(xiàn)代碼

要在LCD屏上完成BMP圖片的顯示,編寫代碼需要分幾步完成,先編寫LCD屏的基本顯示代碼,封裝畫點函數(shù),LCD屏測試沒有問題之后,再編寫B(tài)MP解碼代碼,完成圖片的渲染顯示。

2.1 封裝LCD屏畫點函數(shù)

#include 
#include 
#include 
#include 
unsigned char *fb_mem;
struct fb_var_screeninfo var;//可變參數(shù)
struct fb_fix_screeninfo fix;//固定參數(shù)
?
?
/*畫點*/
void show_pixel(int x,int y,int color)
{
    unsigned long *show32 = NULL;
    /* 定位到LCD屏上的位置*/
    show32=(unsigned long*)(fb_mem+y*var.xres*var.bits_per_pixel/8 + x*var.bits_per_pixel/8); 
 *show32 =color; /*向指向的LCD地址賦數(shù)據(jù)*/
}
?
?
int main(int argc,char**argv)
{
?
     int fb;
     fb=open("/dev/fb0",2);
     if(fb<0)
?        {
?         ? printf("fb0打開失敗!\n");
?         ? return -1;   
?        }
?        
?     /*1. 獲取可變參數(shù)*/
?     ioctl(fb,FBIOGET_VSCREENINFO,&var);
?     printf("x=%d\n",var.xres);
?     printf("y=%d\n",var.yres);
?     printf("bit=%d\n",var.bits_per_pixel);
?     
?     /*2. 獲取固定參數(shù)*/
?     ioctl(fb,FBIOGET_FSCREENINFO,&fix);
?     printf("line_byte=%d\n",fix.line_length);
?     printf("smem_len=%d\n",fix.smem_len);
?     
?     /*3. 映射LCD地址*/
?     fb_mem=mmap(NULL,fix.smem_len,PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
?     
?     int i,j;
?     for(i=0;i;i++)>

2.2 顯示BMP圖片

在工程目錄下準備幾張測試的BMP圖片,程序運行時,在命令行上傳入要顯示的圖片文件地址接口

image-20220124002843632
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#pragma pack(push) /* 將當前pack設置壓棧保存 */
#pragma pack(1)    /* 必須在結構體定義之前使用,這是為了讓結構體中各成員按1字節(jié)對齊 */

/* 1、需要文件信息頭:14個字節(jié) */
typedef struct tagBITMAPFILEHEADER { /* bmfh */
	unsigned short bfType;      //保存圖片類似。 'BM'
	unsigned long  bfSize;      //圖片的大小
	unsigned short bfReserved1;
	unsigned short bfReserved2; 
	unsigned long  bfOffBits;  //RGB數(shù)據(jù)偏移地址
}BITMAPFILEHEADER;

/* 位圖信息頭 */
typedef struct tagBITMAPINFOHEADER { /* bmih */
	unsigned long  biSize;      //結構體大小
	unsigned long  biWidth;		//寬度
	unsigned long  biHeight;	//高度
	unsigned short biPlanes;
	unsigned short biBitCount;	//顏色位數(shù)
	unsigned long  biCompression;
	unsigned long  biSizeImage;
	unsigned long  biXPelsPerMeter;
	unsigned long  biYPelsPerMeter;
	unsigned long  biClrUsed;
	unsigned long  biClrImportant;
} BITMAPINFOHEADER;
#pragma pack(pop) /* 恢復先前的pack設置 */


unsigned char *fbmem=NULL;
struct fb_var_screeninfo var;
struct fb_fix_screeninfo fix;
static int iFileSize = 0;




void show_pixel(int x,int y,int color)
{
	unsigned char *show8=NULL;
	unsigned short *show16=NULL;
	unsigned long *show32 = NULL;
	int red;
	int green;
	int blue;
	/* 定位到LCD屏上的位置 */
	show8 = fbmem + y*var.xres*var.bits_per_pixel/8 + x*var.bits_per_pixel/8;
	show16 = (unsigned short *)show8;
	show32 = (unsigned long *)show8;
	switch(var.bits_per_pixel)
	{
		case 8:

		{
			*show8 = color;
			break;
		}
		case 16:
		{
			/* RGB:565 */
			red = (color >> 16)&0xff;
			green = (color >> 8)&0xff;
			blue  = color&0xff;
			color = ((red>>3)<<11) | ((green>>2)<<6) |(blue>>3);
			*show16 = color;
			break;
		}
		case 32:
		{
			*show32 = color;
			break;
		}
		default:break;
	}
	
	
}

/*映射圖片地址*/
static unsigned char *getbmpadd(char *name)
{
	unsigned char *bmpmem = NULL;
	FILE* filp;
	int fd;
	struct stat t_stat;
	/* 以r+可讀可寫方式打開name */
	filp = fopen(name,"r+");
	if(filp == NULL)
	{
		printf("can't open %s\n",name);
		return NULL;
	}
	/* 把文件指針轉化為文件描述符 */
	fd = fileno(filp);
	/* 獲取文件大小 */
	fstat(fd, &t_stat);
	iFileSize = t_stat.st_size;
	/* 映射 */
	bmpmem = mmap(NULL,iFileSize,PROT_READ|PROT_WRITE,MAP_SHARED,fd, 0);
	if(bmpmem == (unsigned char *)-1)
	{
		printf("can't mmap..\n");
		return NULL;
	}
	return bmpmem;
}
void bmp_destroy(unsigned char *bmpmem)
{
	munmap(bmpmem,iFileSize);
}

void Convert_One_Line(unsigned char *src,unsigned char *dst,int iWidth)
{
	unsigned char *show8=NULL;
	unsigned short *show16=NULL;
	unsigned long *show32 = NULL;
	unsigned char *buf = src;
	int red;
	int green;
	int blue;
	int i;
	/* 定位到LCD屏上的位置 */
	show8 = dst;
	show16 = (unsigned short *)show8;
	show32 = (unsigned long *)show8;
	
	for(i=0;i>3)<<11) | ((green>>2)<<6) |(blue>>3);
				show16++;
				break;
			}
			case 32:
			{
				*show32 = (red<<16)|(green<<8)|blue;
				show32++; // 4個字節(jié)
				break;
			}
			default:break;
		}
	}
}


/* 獲取顏色陣列數(shù)據(jù) */
int getbmpandshow(unsigned char *bmpmem)
{
	/* 定義文件信息頭 */
	BITMAPFILEHEADER *bithead;
	/* 定義文件參數(shù)信息 */
	BITMAPINFOHEADER *bitinfo;
	

	unsigned char *src=NULL;
	unsigned char *dst=NULL;
	int iWidth;
	int iHeight;
	int iBpp;
	int iLineWidth;
	int iRealLineWidth;
	int iFbLineWidth;
	int i=0;
	
	/* 獲取文件信息頭起始地址 */
	bithead =(BITMAPFILEHEADER *)bmpmem;
	/* 獲取位圖信息頭起始地址 */
	bitinfo = (BITMAPINFOHEADER *)(bmpmem + sizeof(BITMAPFILEHEADER));
	
	iWidth  = bitinfo->biWidth;
	iHeight = bitinfo->biHeight;
	iBpp  	= bitinfo->biBitCount;
	printf("iWidth = %d\n",iWidth);
	printf("iHeight = %d\n",iHeight);
	printf("iBpp = %d\n",iBpp);
	
	/* 找到顏色陣列,RGB數(shù)據(jù)的起始地址 */
	src = bmpmem + bithead->bfOffBits;
	
	/* 得到圖片一行字節(jié)數(shù) */
	iLineWidth = iWidth*iBpp/8; 

	/* 向4取整,保證一行必須是4的倍數(shù) */ 
	iRealLineWidth = (iLineWidth+3)&~0x3;  //  iLineWidth % 4  =0

	/* src指向圖片RGB數(shù)據(jù)最后一行的首地址*/
	src += iRealLineWidth*(iHeight-1);

	/* LCD屏一行的總字節(jié)數(shù)  */
	iFbLineWidth = var.xres * var.bits_per_pixel/8;

    /*dst指向LCD的首地址*/
	dst = fbmem;

	for(i=0;i\n",argv[0]);
		return -1;
	}
	lcd_init(argv[1]);

	/* 4、清屏 */
	memset(fbmem,0x0,fix.smem_len);
	
	/* 4.1、顯示圖片-映射圖片地址 */
	bmpmem = getbmpadd(argv[2]); 
	if(NULL == bmpmem)
	{
		printf("can't get bmp address!!\n");
		return -1;
	}
	getbmpandshow(bmpmem); // 顯示圖片
	bmp_destroy(bmpmem); //釋放映射的空間
	return 0;
};i++)>;i++)>

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • lcd
    lcd
    +關注

    關注

    34

    文章

    4411

    瀏覽量

    167100
  • Linux
    +關注

    關注

    87

    文章

    11229

    瀏覽量

    208927
  • BMP
    BMP
    +關注

    關注

    0

    文章

    48

    瀏覽量

    17044
收藏 人收藏

    評論

    相關推薦

    飛凌嵌入式ElfBoard ELF 1板卡-LCD顯示圖片編程示例之開發(fā)板測試

    :~# ./elf1_cmd_lcd_bmp fb0 -b 16 -n logo.bmp logo.bmp.xres=800, .yres=480, .bit=16 .xres_virtual=800, .yres_virt
    發(fā)表于 11-25 09:36

    移植SDL到JZ2440顯示BMP圖片

    LOGO的制作, 韋老師第3期講了如何顯示jpeg圖片, 那么怎么顯示bmp圖片?這次我們借助libSDL來實現(xiàn),我們先移植SDL到Ubun
    發(fā)表于 06-29 11:19

    ILI9325屏幕顯示bmp圖片出現(xiàn)分段

    目前在做從SD卡解析bmp圖片顯示到TFT上的功能。圖片已經(jīng)能顯示出來了。但是出現(xiàn)如圖中圖片分段
    發(fā)表于 01-14 08:57

    請問解碼BMP圖片程序在哪?

    ;BMPFile,x,y,member,denom);}break; case 1://在LCD中間顯示圖片XSize = GUI_BMP_GetXSizeEx(BmpGetData,
    發(fā)表于 09-24 01:57

    bmp圖片LCD開發(fā)板上顯示的方法

    bmp圖片原理,開頭54字節(jié)需要去掉。bmp是3字節(jié)的RGB,而且是內存是翻轉過來的,就是說bmp第一行內存是lcd的最后一行才可以正常
    發(fā)表于 12-27 07:41

    FSMC_液晶顯示BMP圖片.pdf

    FSMC 顯示BMP 圖片,感興趣的可以看看。
    發(fā)表于 01-18 14:16 ?7次下載

    基于STM32芯片的LCD顯示屏的BMP圖片顯示

    基于STM32芯片的LCD顯示屏的BMP圖片顯示
    發(fā)表于 01-18 14:39 ?61次下載

    LCD彩色圖片轉換工具BMP_to_H

    LCD彩色圖片轉換工具BMP_to_H
    發(fā)表于 12-28 10:16 ?11次下載

    嵌入式linux操作framebuffer顯示bmp圖片

    編譯后拷貝進開發(fā)板即可使用使用方法./fb_show_bmp test.bmp顯示圖片由參數(shù)指定,上面指令中test.
    發(fā)表于 11-01 17:06 ?10次下載
    嵌入式<b class='flag-5'>linux</b>操作framebuffer<b class='flag-5'>顯示</b><b class='flag-5'>bmp</b><b class='flag-5'>圖片</b>

    嵌入式LinuxLCD應用編程: 調用giflib庫解碼顯示GIF動態(tài)圖

    一、開發(fā)環(huán)境介紹開發(fā)板:友善之臂Tiny4412LCD型號:S702 、分辨率: 800*480Linux內核版本:Linux 3.5交叉編
    發(fā)表于 11-02 13:21 ?5次下載
    嵌入式<b class='flag-5'>Linux</b>下<b class='flag-5'>LCD</b>應用編程: 調用giflib庫解碼<b class='flag-5'>顯示</b>GIF動態(tài)圖

    剖析BMP圖片文件

    剖析BMP圖片文件
    發(fā)表于 01-23 10:05 ?2次下載

    Linux開發(fā)_文件目錄操作介紹、創(chuàng)建BMP圖片

    介紹C語言文件編程,創(chuàng)建BMP圖片BMP圖片結構介紹,介紹目錄接口編程,Makefile知識點。
    的頭像 發(fā)表于 09-17 15:44 ?1448次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>開發(fā)</b>_文件目錄操作介紹、創(chuàng)建<b class='flag-5'>BMP</b><b class='flag-5'>圖片</b>

    Linux開發(fā)_介紹BMP圖片上下翻轉、添加水印

    介紹BMP圖片上下翻轉、添加水印、通過學習BMP圖片結構學習文件編程。
    的頭像 發(fā)表于 09-17 15:43 ?1822次閱讀

    Linux開發(fā)_BMP圖片編程(翻轉、添加水印)

    接收BMP圖片編程,完成BMP圖片翻轉、水印添加等知識點。
    的頭像 發(fā)表于 09-17 15:33 ?1503次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>開發(fā)</b>_<b class='flag-5'>BMP</b><b class='flag-5'>圖片</b>編程(翻轉、添加水印)

    國產DSP操作教程:LCD圖片顯示實驗(程序讀取圖片

    學習BMP圖像數(shù)據(jù)的存儲格式,并實現(xiàn)LCD圖像數(shù)據(jù)的讀取與顯示
    的頭像 發(fā)表于 10-19 12:33 ?1888次閱讀
    國產DSP操作教程:<b class='flag-5'>LCD</b><b class='flag-5'>圖片</b><b class='flag-5'>顯示</b>實驗(程序讀取<b class='flag-5'>圖片</b>)