linux-數碼相框

平臺:s3c2440 內核版本:linux-2.6.22.6

源碼位置:https://github.com/yogach/digital_photo

描述:本數字相框實現共實現了主頁面、文件瀏覽頁面、圖片模式瀏覽頁面、圖片聯播頁面、設置頁面、聯播模式時間間隔設置頁面。圖片部分支持BMP(自解析)、JPG(JPEG庫)格式的圖片。所有頁面支持觸摸屏(tslib庫)控制。支持LCD頁面顯示。支持標準輸出(stdout)與網絡打印(socket)調試信息。

 

頁面切換框圖:

 

頁面邏輯框圖:

 

數據顯示到lcd:同電子書的lcd顯示刷新

 

 

頁面內的圖標顯示:首先我們需要確定每個圖標的顯示位置,包括起始xy座標結束xy座標,然後獲取圖片原始數據,根據圖標顯示區域的長寬對原始圖片進行縮放近鄰取樣差值算法),然後根據顯示區域的起始地址,將圖片數據寫入到顯存中,然後刷新到LCD顯存,即可完成顯示。

 

縮放算法 :近鄰取樣差值算法https://blog.csdn.net/xjp_xujiping/article/details/79044944

 

觸摸屏控制:輸入事件的獲取使用多線程方式,子線程進入輸入事件的阻塞讀取,讀取到之後喚醒主線程。在每次獲取到觸摸屏原始數據後,將按下位置的XY座標與每個圖標區域的起始結束XY座標進行比較,如果每次按下鬆開(去除按下後滑動的情況)都是處於同一個圖標區域內,則判斷按下了此圖標。

 

頁面的平滑切換:爲了使頁面之間的切換更加平滑,使用多塊顯存空間,用於不同頁面的顯示。在程序開始階段,會分配若干塊顯存,每次顯示頁面之前會根據頁面的名字(char轉化成int後相加)取出對應內存,如果此塊內存的狀態已是REDAY,則可以直接寫入到lcd顯存中,可以減少重新生成圖片數據的時間,使頁面之間的切換更加平滑。

 

文件夾內容信息的獲得:使用scandir函數進行獲取,

int scandir(const char *dir,struct dirent **namelist ,int (*filter)(const void *b),
      int ( * compare )( const struct dirent **, const struct dirent ** ) );

 

函數scandir掃描dir目錄下(不包括子目錄)滿足filter過濾模式的文件,返回的結果是使用compare函數經過排序的,並保存在 namelist中。注意namelist是通過malloc動態分配內存的,所以在使用時要注意釋放內存。alphasort和versionsort 是使用到的兩種排序的函數。   
當函數成功執行時返回找到匹配模式文件的個數,如果失敗將返回-1。namelist內容是dir(dir需要如下這種格式//mnt/才能獲取成功)目錄下的所有文件夾文件,包括".",".."。可使用stat()獲取文件信息後,使用S_ISREG()S_ISDIR()函數判斷是文件夾還是文件。

 

連播頁面圖片顯示:使用多線程方式,子線程負責準備圖片(預先加載圖片數據到指定顯存中)、休眠指定間隔時間、顯示圖片(將準備好的顯存數據刷到lcd顯存中,如果圖片數據未準備好則重新準備),主線程負責接收觸摸屏輸入事件,在接收到觸摸屏事件後,設置互斥量後等待子線程退出。

 

連播頁面文件獲取:使用深度優先的方式遍歷設置的文件夾,最高支持10級遞歸調用,每次獲取10個文件名,然後對獲取的文件(絕對路徑)進行分析,是否爲可支持的顯示文件,如果不行就找到一個能顯示的爲止。

 

 

點擊圖標按鍵效果:當按下圖標時,將LCD顯存中圖標區域內的每個字節數據進行取反處理,代表已經按下了該按鍵。

 

 

瀏覽頁面的文件夾顯示:首先使用scandir()獲取文件夾內容(第5點),讀取到的內容根據文件類型,填充不同的圖標,文件夾名字按ASCII碼方式進行解析,得到Unicode碼後使用freetype庫得到位圖後顯示。每次進行翻頁時,獲取文件夾在namelist中(第5點)的計數,然後進行顯示。

 

 

文件指針mmap: 使用fopen()打開文件以可讀/可寫方式打開文件(fopen與open的區別),使用fstat獲取文件大小後,使用mmap方式映射到內存中。

 

BMP文件的解析:

https://www.cnblogs.com/Matrix_Yao/archive/2009/12/02/1615295.html

JPG文件的解析:

https://blog.csdn.net/xipiaoyouzi/article/details/53257720

 

 

設置間隔頁面長按累加:使用tslib庫得到的觸摸屏原始數據內,會有按下或鬆開的時間值。在首次接收到按下操作時,記錄下此時的觸摸屏原始數據,將之後按下的時間值與初次記錄的值做比較,符合一定時長判斷爲長按。(如果觸摸屏驅動處理長按的方式爲使用定時器重複上報輸入事件)

 

打印信息封裝:電子書項目相同

 

遇到的問題:

使用Scandir()獲取文件夾內容,dir需要如下這種格式//mnt/才能獲取成功。不然就返回獲取到的爲0。很奇怪

 

*piCurFileNumber++;與 (*piCurFileNumber)++; 差異,前一個運行結果是指針指向下一個地址,後一個結果是指針指向的數值自加。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章