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

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

3天內(nèi)不再提示

Linux小項目-數(shù)碼相冊設(shè)計

DS小龍哥-嵌入式技術(shù) ? 來源:DS小龍哥-嵌入式技術(shù) ? 作者:DS小龍哥-嵌入式技 ? 2022-08-14 09:15 ? 次閱讀

1. 前言

這是基于Linux系統(tǒng)開發(fā)板設(shè)計一個小項目-數(shù)碼相冊,在LCD屏上可以顯示完成常見的圖片顯示,翻頁、旋轉(zhuǎn)、縮放等功能。

image-20220122141248516

開發(fā)板采用友善之臂的Tiny4412開發(fā)板,CPU三星的4412,最高主頻1.5GHZ。板子配有8G的EMMC,2G的DDR,運行Linux3.5內(nèi)核,文件系統(tǒng)采用busybox制作的最小根文件系統(tǒng),不帶圖形桌面框架,系統(tǒng)是最小最精簡的系統(tǒng)。

要完成整個項目相冊的功能,需要的東西還是比較多的,首先要編譯安裝各種圖片庫: libjpg,giflib,libpng等等,圖片需要縮放,需要支持縮放算法;LCD界面上的文字,時間采用矢量字體顯示的,還需要交叉編譯安裝freetype庫。然后硬件層,需要編寫LCD屏驅(qū)動(幀緩沖框架),觸摸屏驅(qū)動(輸入子系統(tǒng)),三軸加速度計驅(qū)動(mma7660飛思卡爾的芯片)。

整個項目的代碼布局如下:

image-20220122134342597

如果把整個項目代碼寫完一遍,基本上Linux驅(qū)動、應用層編程都能夠熟悉一遍。

涉及的技術(shù)點總結(jié):

(1)png、jpg、gif等各種開源圖片庫的編譯安裝,完成對應圖片解碼,顯示。整個過程里還需要懂得png、jpg、GIF圖片的構(gòu)造原理,如何讀取數(shù)據(jù),如何提取rgb數(shù)據(jù),最終在LCD屏上完成顯示。

(2)LCD驅(qū)動編寫,首先得了解Linux幀緩沖框架原理,明白LCD屏的時序,才能編寫驅(qū)動。應用層需要明白如何針對幀緩沖框架完成應用編程,實現(xiàn)畫點、畫線、文字等基本顯示。

(3)觸摸屏驅(qū)編寫,觸摸屏驅(qū)動芯片是FT5X06,這個IIC接口的芯片,編寫觸摸屏驅(qū)動需要熟悉IIC子系統(tǒng)、輸入子系統(tǒng)、內(nèi)核中斷、工作隊列等框架,因為觸摸屏芯片支持筆中斷,需要注冊中斷,在中斷服務(wù)函數(shù)里調(diào)用工作隊列實時讀取數(shù)據(jù)。 應用層還需要適配tslib庫接口,讓tslib去讀取輸入子系統(tǒng)上傳的坐標,還能完成校準,測試等功能,最終在自己工程內(nèi)再封裝函數(shù)去讀取tslib接口返回的坐標數(shù)據(jù),完成觸屏屏邏輯處理。

(4)三軸加速度mma7660驅(qū)動編寫,通過三軸加速度測量開發(fā)板的姿態(tài),完成數(shù)碼相冊里圖片的自動上下左右翻轉(zhuǎn),手機相冊都有這個功能,橫豎屏切換。

(5)按鍵驅(qū)動編寫,數(shù)碼相冊支持按鍵翻頁、觸摸屏滑動翻頁、自動圖片播放(幻燈片)等功能,所以還需要編寫按鍵驅(qū)動,按鍵驅(qū)動采用雜項字符設(shè)備編寫,通過ioctl接口上傳按鍵值。

(6)矢量字體庫編譯安裝,界面上需要顯示各種文字提示、時間等信息。用到矢量字體ttc,ttf等。

圖片的翻頁采用雙向鏈表完成,支持左右翻頁,更新鏈表時,將指定目錄下所有圖片加到雙向鏈表里,通過按鍵、觸摸屏、自動播放時,從鏈表里獲取圖片地址完成顯示。

2. 涉及到源代碼

2.1 png圖片顯示

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define LCD_DEVICE "/dev/fb0"

int lcd_fd;
struct fb_var_screeninfo vinfo;//可變參數(shù)
struct fb_fix_screeninfo finfo; //固定參數(shù)
unsigned char *lcd_mem=NULL; //LCD首地址
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;

int image_height;
int image_width;
unsigned char *image_buffer[4];
int video_fd;
void LCD_DrawPoint(u32 x,u32 y,u32 c);
u32 LCD_ReadPoint(u32 x,u32 y);


/*顯示PNG文件*/
int display_png(u32 x,u32 y,char* filename) 
{
	FILE *fp;
	png_structp png_ptr;
	png_infop info_ptr;
	png_uint_32 width, height;
	int bit_depth, color_type, interlace_type, number_passes;
	u32 i,j;
	u32 x0;
	u32 rgb24,b_rgb24;
	u8 r,g,b,a;
	u8 b_r,b_g,b_b;
	u8 R,G,B;
	
    if((fp = fopen(filename,"rb")) == NULL)
    {
      printf("%s 文件打開失敗.\n",filename);
      return -1;
    }
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL, NULL, NULL);
    /*需要分配/初始化內(nèi)存以獲取圖像信息*/
	info_ptr = png_create_info_struct(png_ptr);
	/*設(shè)置PNG圖片的文件指針*/
    png_init_io(png_ptr,fp);
    png_read_info(png_ptr,info_ptr);
    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,&interlace_type, NULL, NULL);  
	printf("圖片寬度:[%4d]\n",width);
	printf("圖片高度:[%4d]\n",height);
	printf("顏色位數(shù):[%4d]\n",bit_depth); //ARGB
	
    /*讀取圖像的最簡單方法:*/
    png_bytep row_pointers[height];

	/*清除指針數(shù)組*/
	for(i = 0; i < height; i++)
	{
		row_pointers[i] = NULL;
		row_pointers[i] = malloc(width * 4); /* RGBA */
		memset(row_pointers[i], 0, width * 4);
	}
	/*讀取整個PNG圖像*/
	png_read_image(png_ptr,row_pointers);

    for(i = 0; i < height; i++)
    {
		x0=x;
		for(j = 0; j < width * 4; j += 4)
		{
			/*得到圖片顏色*/
			r=row_pointers[i][j + 0];
			g=row_pointers[i][j + 1];
			b=row_pointers[i][j + 2];
			a=row_pointers[i][j + 3];
			
			/*讀取當前屏幕點的背景顏色*/
			b_rgb24=LCD_ReadPoint(x0,y);
			b_r=b_rgb24>>16&0xFF;
			b_g=b_rgb24>>8&0xFF;
			b_b=b_rgb24>>0&0xFF;
			
			/*合成屏幕背景顏色*/
			R = (unsigned char)(r * (a / 255.0) + (b_r * (255 - a)) / 255.0);
			G = (unsigned char)(g * (a / 255.0) + (b_g * (255 - a)) / 255.0);
			B = (unsigned char)(b * (a / 255.0) + (b_b * (255 - a)) / 255.0);
		
			/*顯示數(shù)據(jù)*/
			rgb24=R<<16|G<<8|B;
			LCD_DrawPoint(x0,y,rgb24);
			
			/*坐標自增*/
			x0++;
		}
		y++;
	}
    /* 讀取文件的其余部分,并在info_ptr中獲取其他塊-必需*/
    png_read_end(png_ptr, info_ptr);
   /*讀取后清理,并釋放已分配的所有內(nèi)存-必需*/
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    /* 統(tǒng)一釋放內(nèi)存 */
	for(i = 0; i < height; i++)
	{
		free(row_pointers[i]);
	}
    /*關(guān)閉文件*/
    fclose(fp);
    return 0;
}


/*
函數(shù)功能: 封裝畫點函數(shù)
函數(shù)參數(shù): u32 x,u32 y,u16 c
*/
void LCD_DrawPoint(u32 x,u32 y,u32 c)
{
	 u32 *lcd_p=(u32*)(lcd_mem+vinfo.xres*vinfo.bits_per_pixel/8*y+x*vinfo.bits_per_pixel/8);
	 *lcd_p=c;
}


/*
函數(shù)功能: 封裝讀點函數(shù)
函數(shù)參數(shù): u32 x,u32 y,u16 c
*/
u32 LCD_ReadPoint(u32 x,u32 y)
{
	 u32 *lcd_p=(u32*)(lcd_mem+vinfo.xres*vinfo.bits_per_pixel/8*y+x*vinfo.bits_per_pixel/8);
	 return *lcd_p;
}

int main(int argc,char **argv)
{
	int err;
	if(argc!=2)
	{
		printf("./app \n");
		return 0;
	}
	
	/*1. 打開設(shè)備文件*/
	lcd_fd=open(LCD_DEVICE,O_RDWR);
	if(lcd_fd<0)
	{
		printf("%s 設(shè)備文件打開失敗.\n",LCD_DEVICE);
		return 0;
	}
	/*2. 獲取可變參數(shù)*/
	ioctl(lcd_fd,FBIOGET_VSCREENINFO,&vinfo);
	printf("x=%d,y=%d,pixel=%d\n",vinfo.xres,vinfo.yres,vinfo.bits_per_pixel);
	
	/*3. 獲取固定參數(shù)*/
	ioctl(lcd_fd,FBIOGET_FSCREENINFO,&finfo);
	printf("smem_len=%d\n",finfo.smem_len);
	printf("line_length=%d\n",finfo.line_length);

	/*4. 映射LCD地址*/
	lcd_mem=mmap(NULL,finfo.smem_len,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);
	if(lcd_mem==NULL)
	{
		printf("映射LCD地址失敗.\n");
		return -1;
	}
	//memset(lcd_mem,0xFFFFFF,finfo.smem_len);
	
	/*5. 顯示PN圖片*/
	display_png(0,0,argv[1]);
	
	close(lcd_fd);
	return 0;
}
復制代碼

2.2 jpg圖片顯示

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
?
#include 
#include 
?
struct fb_var_screeninfo var;   //可變參數(shù)
struct fb_fix_screeninfo fix;   //固定參數(shù)
unsigned char *fb_mem=NULL;     //LCD屏的首地址
?
/*
函數(shù)功能: 畫點
*/
void Show_Pixel(int x,int y,int color)
{
    unsigned int *lcd=(unsigned int *)(fb_mem+y*var.xres*var.bits_per_pixel/8+x*var.bits_per_pixel/8);
    *lcd=color; //顏色賦值
}
?
?
//顯示JPEG  jpeglib
int LCD_ShowJPEG(int x,int y,unsigned char *file)
{
  struct jpeg_decompress_struct cinfo; //存放圖像的數(shù)據(jù)
  struct jpeg_error_mgr jerr; //存放錯誤信息
  FILE     *infile;
  unsigned int *dst=(unsigned int *)fb_mem;
  unsigned char *buffer;
    unsigned int i;
    unsigned int color;
    
  /* 打開圖像文件*/
  if ((infile = fopen(file, "rb")) == NULL) 
    {
    perror("jpeg文件打開失敗!\n");
    return -1;
   }
?
  /*init jpeg壓縮對象錯誤處理程序*/
  cinfo.err = jpeg_std_error(&jerr); //初始化標準錯誤,用來存放錯誤信息
  jpeg_create_decompress(&cinfo);  //創(chuàng)建解壓縮結(jié)構(gòu)信息
   
  /*將jpeg壓縮對象綁定到infile*/
  jpeg_stdio_src(&cinfo, infile);
?
  /*讀jpeg頭*/
  jpeg_read_header(&cinfo, TRUE);
  
  /*開始解壓*/
  jpeg_start_decompress(&cinfo);
  
  printf("JPEG圖片高度: %d\n",cinfo.output_height);
  printf("JPEG圖片寬度: %d\n",cinfo.output_width);
  printf("JPEG圖片顏色位數(shù)(字節(jié)單位): %d\n",cinfo.output_components);
  
  /*為一條掃描線上的像素點分配存儲空間,一行一行的解碼*/
  buffer = (unsigned char *)malloc(cinfo.output_width *cinfo.output_components);
  
    //將圖片內(nèi)容顯示到framebuffer上,cinfo.output_scanline表示當前行的位置,讀取數(shù)據(jù)是會自動增加
  while(cinfo.output_scanline < cinfo.output_height) 
? ?  {
? ? ? ? ? //讀取一行的數(shù)據(jù) ? ?
? ? ? ? ?jpeg_read_scanlines(&cinfo,&buffer,1);
?        for(i = 0; i;>

2.3 gif圖片顯示

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
struct fb_var_screeninfo var;	//可變參數(shù)
struct fb_fix_screeninfo fix;	//固定參數(shù)
unsigned char *fb_mem=NULL; 	//LCD屏的首地址

/*
函數(shù)功能: 畫點
*/
void LCD_WritePoint(int x,int y,int color)
{
	unsigned int *lcd=(unsigned int *)(fb_mem+y*var.xres*var.bits_per_pixel/8+x*var.bits_per_pixel/8);
	*lcd=color; //顏色賦值
}

//幀緩沖顯示
void FrameBufferDraw(int x,int y,int image_w,int image_h,unsigned char *rgbBuf)
{
	int w,h;
	unsigned char r,g,b; 
	unsigned int c;
	/*將圖像數(shù)據(jù)顯示在LCD屏幕上*/
	unsigned char *rgb_p=rgbBuf;
	for(h=0;hColors[GifRow[idxW]];
			*rgbBuf++ = ColorMapEntry->Blue;
			*rgbBuf++ = ColorMapEntry->Green;
            *rgbBuf++ = ColorMapEntry->Red;    
        }
    }
}

//顯示GIF圖像
int LCD_DisplayGIF(int x,int y,unsigned char *file)
{
	int error=0;
	int size;
	int i;
	GifRowType *Buffer;
	GifFileType *fp;
    /*1. 打開圖片文件*/
	fp=DGifOpenFileName(file,&error);
	if(fp==NULL)return -1;
	printf("GIF圖片尺寸:%dx%d\n",fp->SWidth,fp->SHeight);
	
	/*2. 內(nèi)存空間申請、初始化*/
	Buffer=(GifRowType*)malloc(fp->SHeight*sizeof(GifRowType));
	
	/*一行字節(jié)大小*/
	size = fp->SWidth*sizeof(GifPixelType);
	Buffer[0]=(GifRowType)malloc(size);
	
	/*將其顏色設(shè)置為BackGround*/
    for(i=0;iSWidth;i++)
	{
		Buffer[0][i]=fp->SBackGroundColor;
	}
	
	/*分配其他行,并將它們的顏色也設(shè)置為背景 */
	for(i=1;iSHeight;i++)
	{
		Buffer[i]=(GifRowType)malloc(size);
		memcpy(Buffer[i],Buffer[0],size);
	}
	
	/*3. 顯示圖片*/
	ColorMapObject *colorMap=NULL;
	GifByteType *extension=NULL;
	GifRecordType gRecordType=UNDEFINED_RECORD_TYPE;

	int InterlacedOffset[]={0,4,2,1};  // The way Interlaced image should
	int InterlacedJumps[]={8,8,4,2};   // be read - offsets and jumps...
	unsigned char rgbBuf[800 * 480]={0};
	
	int extCode = 0;
	int row = 0;
	int col = 0;
	int width = 0;
	int height = 0;
	int iW = 0;
	int iH = 0;
	do
	{
		if(DGifGetRecordType(fp,&gRecordType)==GIF_ERROR)break;
		
		switch(gRecordType)
		{
			case IMAGE_DESC_RECORD_TYPE:
				if(DGifGetImageDesc(fp)==GIF_ERROR)break;

				row=fp->Image.Top;
				col=fp->Image.Left;
				width=fp->Image.Width;
				height=fp->Image.Height;

				if(fp->Image.Interlace)
				{
					for(iH=0;iH<4;iH++)
					{
						for(iW=row+InterlacedOffset[iH];iWImage.ColorMap?fp->Image.ColorMap:fp->SColorMap);
				if(colorMap==NULL)
				{
					break;
				}

				GifBufferToRgb888(colorMap,rgbBuf,Buffer,fp->SWidth,fp->SHeight);
				//將圖像顯示在LCD屏上
				FrameBufferDraw(x,y,fp->SWidth,fp->SHeight,rgbBuf);
				//幀間隔時間
				usleep(1000*50);
				break;

			case EXTENSION_RECORD_TYPE:
				/* 跳過文件中的所有擴展塊*/
				if(DGifGetExtension(fp,&extCode,&extension)==GIF_ERROR)break;

				while(extension!=NULL)
				{
					if(DGifGetExtensionNext(fp, &extension) == GIF_ERROR)break;
				}
				break;
				
			case TERMINATE_RECORD_TYPE:
				break;

			default:
				break;
		}
	}while(gRecordType!=TERMINATE_RECORD_TYPE);
	
	/*4. 釋放空間*/
	for(i =0;iSHeight;i++)
    {
       free(Buffer[i]);
    }
    free(Buffer);
    DGifCloseFile(fp,&error);
    return 0;
}

int main(int argc,char **argv)
{
	if(argc!=2)
	{
		printf("./app \n");
		return 0;
	}
	
	int fd=open("/dev/fb0",O_RDWR);
	if(fd<0)
	{
		perror("設(shè)備文件打開失敗");
		return 0;
	}
	
	/*1. 獲取LCD屏的可變形參*/
	ioctl(fd,FBIOGET_VSCREENINFO,&var);
	printf("分辨率:%d*%d\n",var.xres,var.yres);
	printf("像素點位數(shù):%d\n",var.bits_per_pixel);
	
	/*2. 獲取LCD屏的固定形參*/
	ioctl(fd,FBIOGET_FSCREENINFO,&fix);
	printf("映射的長度:%d\n",fix.smem_len);
	printf("一行的字節(jié)數(shù):%d\n",fix.line_length);
	
	/*3. 映射LCD緩沖區(qū)地址到進程空間*/
	fb_mem=mmap(NULL,fix.smem_len,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
	if(fb_mem==NULL)
	{
		perror("空間映射失敗!\n");
		return 0;
	}
	
	/*4. 控制顯示屏*/
	memset(fb_mem,0xFFFFFF,fix.smem_len); //將屏幕清屏為白色
	
	while(1)
	{
		printf("GIF圖片顯示狀態(tài):%d\n",LCD_DisplayGIF(100,100,argv[1]));
	}
	
	munmap(fb_mem,fix.smem_len);
	close(fd);
	return 0;
}
復制代碼圖片文件>+height;iw+=interlacedjumps[ih])>;h++)>

2.4 矢量字體調(diào)用顯示

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 

#include 
#include FT_FREETYPE_H
#include FT_STROKER_H

#define LCD_DEVICE "/dev/fb0"
int lcd_fd;
struct fb_var_screeninfo vinfo;//可變參數(shù)
struct fb_fix_screeninfo finfo; //固定參數(shù)
unsigned char *lcd_mem=NULL; //LCD首地址
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;

/*定義一個結(jié)構(gòu)體存放矢量字體的配置*/
struct FREE_TYPE_CONFIG
{
	FT_Library    library;
	FT_Face       face;
	FT_GlyphSlot  slot;
	FT_Vector     pen;                    /* untransformed origin  */
	FT_Error      error;
	FT_BBox  bbox;
	FT_Glyph  glyph;
};
struct FREE_TYPE_CONFIG FreeTypeConfig;



/*
函數(shù)功能: 封裝畫點函數(shù)
函數(shù)參數(shù): u32 x,u32 y,u16 c
*/
void LCD_DrawPoint(u32 x,u32 y,u32 c)
{
	 u32 *lcd_p=(u32*)(lcd_mem+vinfo.xres*vinfo.bits_per_pixel/8*y+x*vinfo.bits_per_pixel/8);
	 *lcd_p=c;
}


/*
函數(shù)功能: 封裝讀點函數(shù)
函數(shù)參數(shù): u32 x,u32 y,u16 c
*/
u32 LCD_ReadPoint(u32 x,u32 y)
{
	 u32 *lcd_p=(u32*)(lcd_mem+vinfo.xres*vinfo.bits_per_pixel/8*y+x*vinfo.bits_per_pixel/8);
	 return *lcd_p;
}


/*	LCD顯示矢量字體的位圖信息
 *		bitmap : 要顯示的字體的矢量位圖
 *		x : 顯示的x坐標
 *		y : 顯示的y坐標
 */
void LCD_DrawBitmap(FT_Bitmap* bitmap,FT_Int x,FT_Int y)
{
  	FT_Int i,j,p,q;
  	FT_Int x_max=x+bitmap->width;
  	FT_Int y_max=y+bitmap->rows;

	/* 將位圖信息循環(huán)打印到屏幕上 */
	for(i=x,p=0;ix_max)||(j>y_max)||(i<0)||(j<0))continue;
			if(bitmap->buffer[q*bitmap->width+p]!=0)
			{
				LCD_DrawPoint(i, j,0xFF0033);
			}
			else
			{
				LCD_DrawPoint(i, j,0xFFFFFF);
			}
		}
	}
}

/*
函數(shù)功能: 初始化FreeType配置
*/
int InitConfig_FreeType(char *font_file)
{
	FT_Error      error;
	/*1. 初始化freetype庫*/
	error=FT_Init_FreeType(&FreeTypeConfig.library);
	if(error)
	{
		printf("freetype字體庫初始化失敗.\n");
		return -1;
	}

	/*2. 打開加載的字體文件*/
 	error=FT_New_Face(FreeTypeConfig.library,font_file,0,&FreeTypeConfig.face);
  	if(error)
  	{
		printf("矢量字體文件加載失敗.\n");
		return -2;
	}
	return 0;
}

/*
函數(shù)功能: 釋放FreeType配置
*/
void FreeType_Config(void)
{
	FT_Done_Face(FreeTypeConfig.face);
  	FT_Done_FreeType(FreeTypeConfig.library);
}

/*
函數(shù)功能: 在LCD屏顯示一串文本數(shù)據(jù)
函數(shù)參數(shù):
	u32 x   坐標位置
	u32 y   坐標位置
	u32 size 字體大小
	wchar_t *text 顯示的文本數(shù)據(jù)
*/
int LCD_DrawText(u32 x,u32 y,u32 size,wchar_t *text)
{
	FT_Error      error;
	int i = 0;
	int bbox_height_min = 10000;
	int bbox_height_max = 0;
		
	/*3. 設(shè)置字符的像素的大小為size*size*/
	error=FT_Set_Pixel_Sizes(FreeTypeConfig.face,size,0);
	if(error)
	{
		printf("字符的像素大小設(shè)置失敗.\n");
		return -1;
	}
	
	/*4. 設(shè)置字體文件的輪廓的插槽*/
	FreeTypeConfig.slot=FreeTypeConfig.face->glyph;

	/* 設(shè)置坐標為原點坐標
	 * 將LCD坐標轉(zhuǎn)換成笛卡爾坐標
	 * 單位是 1/64 Point
	 */
	FreeTypeConfig.pen.x=x*64;
  	FreeTypeConfig.pen.y=(vinfo.yres-size-y)*64;

	/*5. 循環(huán)的將文字顯示出來*/
	for(i=0;iFreeTypeConfig.bbox.yMin)bbox_height_min=FreeTypeConfig.bbox.yMin;
		if(bbox_height_maxbitmap,
						FreeTypeConfig.slot->bitmap_left,
						vinfo.yres-FreeTypeConfig.slot->bitmap_top);

		if(FreeTypeConfig.slot->bitmap_left+size*2>vinfo.xres)
		{
			FreeTypeConfig.pen.x=0; //更新X坐標位置
			FreeTypeConfig.pen.y=(vinfo.yres-size-y-size)*64; //更新Y坐標位置
		}
		else
		{
			/* 更新原點坐標位置 */
			FreeTypeConfig.pen.x+=FreeTypeConfig.slot->advance.x;
			FreeTypeConfig.pen.y+=FreeTypeConfig.slot->advance.y;
		}
	}
	return 0;
}

int main(int argc,char **argv)
{	
	if(argc!=2)
	{
		printf("./app \n");
		return 0;
	}
	
	/*1. 打開設(shè)備文件*/
	lcd_fd=open(LCD_DEVICE,O_RDWR);
	if(lcd_fd<0)
	{
		printf("%s open error.\n",LCD_DEVICE);
		return 0;
	}
	/*2. 獲取可變參數(shù)*/
	ioctl(lcd_fd,FBIOGET_VSCREENINFO,&vinfo);
	printf("x=%d,y=%d,pixel=%d\n",vinfo.xres,vinfo.yres,vinfo.bits_per_pixel);
	
	/*3. 獲取固定參數(shù)*/
	ioctl(lcd_fd,FBIOGET_FSCREENINFO,&finfo);
	printf("smem_len=%d\n",finfo.smem_len);
	printf("line_length=%d\n",finfo.line_length);

	/*4. 映射LCD地址*/
	lcd_mem=mmap(NULL,finfo.smem_len,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);
	if(lcd_mem==NULL)
	{
		printf("映射LCD地址失敗.\n");
		return -1;
	}
	memset(lcd_mem,0xFFFFFF,finfo.smem_len);
	
	/*5. 初始化配置FreeType*/
	InitConfig_FreeType(argv[1]);
	
	/*6. 在指定位置顯示文本*/
	/*
	wcslen() 函數(shù)用于計算寬字符的個數(shù),支持區(qū)分中文和英文字符,文本需要在UTF-8編碼下。
	定義寬字符串示例:
	wchar_t *wp=L"1234567890中國"; //12
	printf("wcslen p:%d\n",wcslen(wp)); 返回值是12
	*/
	LCD_DrawText(50,56*0,56,L"北京萬邦易嵌科技有限公司");
	LCD_DrawText(150,56*1,56,L"www.wanbangee.com");
	LCD_DrawText(200,56*3,48,L"FreeType矢量字體");
	LCD_DrawText(150,56*5,80,L"Linux驅(qū)動開發(fā)");
	/*7. 釋放FreeType配置*/
	FreeType_Config();
	
	close(lcd_fd);
	return 0;
})bbox_height_max=freetypeconfig.bbox.ymax;>(text);i++)>;i++,p++)>

審核編輯:湯梓紅

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

    關(guān)注

    34

    文章

    4426

    瀏覽量

    167494
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11304

    瀏覽量

    209498
  • 開發(fā)板
    +關(guān)注

    關(guān)注

    25

    文章

    5050

    瀏覽量

    97471
收藏 人收藏

    評論

    相關(guān)推薦

    Linux驅(qū)動開發(fā)_數(shù)碼相冊項目、360WIFI驅(qū)動移植介紹

    這篇文章介紹兩個知識點: 數(shù)碼相冊要求介紹、貼出案例代碼、介紹360隨身WIFI的驅(qū)動移植注意事項。
    的頭像 發(fā)表于 09-17 15:51 ?1733次閱讀
    <b class='flag-5'>Linux</b>驅(qū)動開發(fā)_<b class='flag-5'>數(shù)碼相冊</b><b class='flag-5'>項目</b>、360WIFI驅(qū)動移植介紹

    基于STM32設(shè)計的數(shù)碼相冊

    項目是基于STM32設(shè)計的數(shù)碼相冊,能夠通過LCD顯示屏解碼顯示主流的圖片,支持bmp、jpg、gif等格式。用戶可以通過按鍵或者觸摸屏來切換圖片,同時還可以旋轉(zhuǎn)顯示,并能夠自適應居中顯示,小尺寸圖片居中顯示,大尺寸圖片自動縮小顯示(超出屏幕范圍)。圖片從SD卡中獲取。
    的頭像 發(fā)表于 06-24 21:14 ?14.6w次閱讀
    基于STM32設(shè)計的<b class='flag-5'>數(shù)碼相冊</b>

    單片機控制的DIY數(shù)碼相冊顯示

    本帖最后由 eehome 于 2013-1-5 09:52 編輯 單片機控制的DIY數(shù)碼相冊顯示
    發(fā)表于 08-15 23:05

    單片機小項目

    本帖最后由 eehome 于 2013-1-5 09:47 編輯 單片機小項目
    發(fā)表于 08-26 11:59

    求做小項目

    求助:初學單片機,想做個小項目,哪位同仁可以介紹介紹有什么好項目學習一下的。{:soso_e132:}
    發(fā)表于 09-27 00:32

    【Aworks申請】基于ARM9的電子相冊

    申請理由:本人是一名嵌入式開發(fā)從業(yè)者,對嵌入式開發(fā)有著濃厚的興趣,本套開發(fā)板具有極其豐富的學習資源,非常希望能夠獲得此次機會,對ARM9嵌入式系統(tǒng)開發(fā)有很大的幫助。項目描述:通過開發(fā)板的學習之后,制作一個簡單的可以控制的電子數(shù)碼相冊,簡單,美觀。為今后的工作學習打下良好的
    發(fā)表于 07-15 08:58

    適合新手做的小項目

    接觸Labview一個月,有沒有適合新手做的小項目,求介紹下
    發(fā)表于 08-09 14:14

    單片機小項目開源分享

    轉(zhuǎn)眼間已經(jīng)工作一年,目前從事linux/android驅(qū)動工作,將大學期間單片機的小項目開源出來,供大家交流學習,比較簡單。源碼在git clone http://www.github.com
    發(fā)表于 09-17 11:33

    【YOXIOS X3開發(fā)板(基于Linux的GUI)試用連載】基于linux開發(fā)小項目

    項目名稱:基于linux開發(fā)小項目試用計劃:申請理由:我公司主要的產(chǎn)品是使用linux系統(tǒng)來開發(fā)各種產(chǎn)品。而我只會使用普通的單片機開發(fā),一直想學習l
    發(fā)表于 07-27 15:05

    單片機的一些小項目資料

    單片機的一些小項目,單片機入門必備,適合初學者
    發(fā)表于 11-18 17:24 ?11次下載

    Linux應用小項目的解碼庫移植源代碼免費下載

    本文檔的主要內(nèi)容詳細介紹的是Linux應用小項目源碼 解碼庫移植、調(diào)用的項目,源碼中有詳細注釋,用交叉工具鏈直接可編譯。
    發(fā)表于 10-24 08:00 ?0次下載

    STM32學習——入門小項目

    STM32學習——入門小項目
    發(fā)表于 12-07 17:21 ?72次下載
    STM32學習——入門<b class='flag-5'>小項目</b>

    Arduino Bootcamp師生小項目

    電子發(fā)燒友網(wǎng)站提供《Arduino Bootcamp師生小項目.zip》資料免費下載
    發(fā)表于 07-28 11:22 ?0次下載
    Arduino Bootcamp師生<b class='flag-5'>小項目</b>

    FPGA增強了數(shù)碼相冊功能

    隨著我們不斷以像素為單位捕獲生活快照,我們正在積累一系列軟件工具和設(shè)備來查看,編輯,存儲,個性化和共享我們的數(shù)碼照片。一個能夠可靠地提供所有這些功能的單一、易于使用的系統(tǒng)將簡化和增強照片制作過程。
    的頭像 發(fā)表于 10-25 11:25 ?923次閱讀
    FPGA增強了<b class='flag-5'>數(shù)碼相冊</b>功能

    通過ESP32制作數(shù)碼相冊

    電子發(fā)燒友網(wǎng)站提供《通過ESP32制作數(shù)碼相冊.zip》資料免費下載
    發(fā)表于 06-16 11:30 ?2次下載
    通過ESP32制作<b class='flag-5'>數(shù)碼相冊</b>