1. 程式人生 > >linux下實現對framebuffer(/dev/fb0)的截圖操作

linux下實現對framebuffer(/dev/fb0)的截圖操作

在linux系統中,使用framebuffer來提供使用者態程序直接操作顯示屏的功能.

在嵌入式系統開發中,需要對顯示屏的內容進行擷取,實現一個lcd截圖工具實現對顯示屏內容的擷取,儲存為bmp格式.

一個bmp檔案有四部分組成:


其中點陣圖檔案頭內容如下:

    WORD    bfType; 
    DWORD   bfSize; 
    WORD    bfReserved1; 
    WORD    bfReserved2; 
    DWORD   bfOffBits; 
bfType 說明檔案的型別,該值必需是0x4D42,也就是字元'BM',否則表示根本不是BMP
bfSize 說明該點陣圖檔案的大小,用位元組為單位
bfReserved1 保留,必須設定為0
bfReserved2 保留,必須設定為0
bfOffBits 說明從檔案頭開始到實際的圖象資料之間的位元組的偏移量。這個引數是非常有用的,因為點陣圖資訊頭和調色盤的長度會根據不同情況而變化,所以你可以用這個偏移值迅速的從檔案中讀取到位資料。
點陣圖資訊段內容如下:
    DWORD  biSize; 
    LONG   biWidth; 
    LONG   biHeight; 
    WORD   biPlanes; 
    WORD   biBitCount 
    DWORD  biCompression; 
    DWORD  biSizeImage; 
    LONG   biXPelsPerMeter; 
    LONG   biYPelsPerMeter; 
    DWORD  biClrUsed; 
    DWORD  biClrImportant; 
biSize 說明BITMAPINFOHEADER結構所需要的位元組數
biWidth 說明圖象的寬度,以象素為單位
biHeight 說明圖象的高度,以象素為單位。注:這個值除了用於描述影象的高度之外,它還有另一個用處,就是指明該影象是倒向的點陣圖,還是正向的點陣圖。如果該值是一個正數,說明影象是倒向的,即:資料的第一行其實是影象的最後一行,如果該值是一個負數,則說明影象是正向的。大多數的BMP檔案都是倒向的點陣圖,也就是時,高度值是一個正數。
biPlanes 表示bmp圖片的平面屬,顯然顯示器只有一個平面,所以恆等於1
biBitCount 說明位元數/象素,其值為1、4、8、16、24、或32。
biCompression 說明圖象資料壓縮的型別,其中: 

BI_RGB:沒有壓縮

BI_RLE8:每個象素8位元的RLE壓縮編碼,壓縮格式由2位元組組成(重複象素計數和顏色索引);

BI_RLE4:每個象素4位元的RLE壓縮編碼,壓縮格式由2位元組組成

BI_BITFIELDS:每個象素的位元由指定的掩碼決定。

BI_JPEG:JPEG格式

biSizeImage 說明圖象的大小,以位元組為單位。當用BI_RGB格式時,可設定為0。
biXPelsPerMeter 說明水平解析度,用象素/米表示。
biYPelsPerMeter 說明垂直解析度,用象素/米表示。
biClrUsed 說明點陣圖實際使用的彩色表中的顏色索引數(設為0的話,則說明使用所有調色盤項)。
biClrImportant 說明對圖象顯示有重要影響的顏色索引的數目,如果是0,表示都重要。

由於當前嵌入式裝置使用的顯示介面為RGB565格式,選擇biBitCount為16的格式來儲存顯示屏資料.顯示屏大小為800x600.

實現程式碼如下:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#include <stdio.h>
#include <unistd.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>

static unsigned char sg_BHeader[] = {
    0x42, 0x4D, 0x36, 0x58, 0x02, 0x00, 0x00, 0x00,  0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, 
    0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00,  0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
#define RGB565TO1555(rgb) ((unsigned short)((unsigned short)(rgb & 0x001f) | ((unsigned short)(rgb & 0xffc0) >> 1)))
void SaveBMPFile(unsigned char *raw, char *filename)
{
    unsigned short *p = (unsigned short *)raw;
    typedef unsigned int UINT;
    typedef unsigned char UCHAR;
    UINT m_Width = 800, m_Height = 480;
    UINT i, j;
    int bmp = open(filename, O_WRONLY | O_CREAT);
    if(bmp < 0)
        return;
    sg_BHeader[0x02] = (UCHAR)(m_Width * m_Height * 2 + 0x36) & 0xff;
    sg_BHeader[0x03] = (UCHAR)((m_Width * m_Height * 2 + 0x36) >> 8) & 0xff;
    sg_BHeader[0x04] = (UCHAR)((m_Width * m_Height * 2 + 0x36) >> 16) & 0xff;
    sg_BHeader[0x05] = (UCHAR)((m_Width * m_Height * 2 + 0x36) >> 24) & 0xff;
    sg_BHeader[0x12] = (UCHAR)m_Width & 0xff;
    sg_BHeader[0x13] = (UCHAR)(m_Width >> 8) & 0xff;
    sg_BHeader[0x14] = (UCHAR)(m_Width >> 16) & 0xff;
    sg_BHeader[0x15] = (UCHAR)(m_Width >> 24) & 0xff;
    sg_BHeader[0x16] = (UCHAR)m_Height & 0xff;
    sg_BHeader[0x17] = (UCHAR)(m_Height >> 8) & 0xff;
    sg_BHeader[0x18] = (UCHAR)(m_Height >> 16) & 0xff;
    sg_BHeader[0x19] = (UCHAR)(m_Height >> 24) & 0xff;
    write(bmp, sg_BHeader, sizeof(sg_BHeader));
    for(i = 0; i < m_Height; i++)
    {
        unsigned short *c = p + (m_Height - 1 - i) * m_Width;
        unsigned short cc;
        for(j = 0; j < m_Width; j++)
        {
            cc = RGB565TO1555(*(c + j));
//            cc = *(c + j);
            write(bmp, &cc, 2);
        }
    }
    close(bmp);
}
int main(int argc, char *argv[])
{
    unsigned char buf[800*480*2];
    char *filename;
    int fb;

    
    fb = open("/dev/fb0", O_RDONLY);
    if(fb < 0)
        exit(1);
    if(argc == 2)
        filename = argv[1];
    else
        exit(1);
    printf("reading screen...\n");
    read(fb, buf, 800*480*2);
    close(fb);
    printf("saving screen...\n");
    SaveBMPFile(buf, filename);
    printf("file %s created successfully\n", filename);
    exit(0);
}

相關推薦

linux實現framebuffer(/dev/fb0)的操作

在linux系統中,使用framebuffer來提供使用者態程序直接操作顯示屏的功能. 在嵌入式系統開發中,需要對顯示屏的內容進行擷取,實現一個lcd截圖工具實現對顯示屏內容的擷取,儲存為bmp格式. 一個bmp檔案有四部分組成: 其中點陣圖檔案頭內容如下: WO

linux Framebuffer(/dev/fb0)

linux Framebuffer(/dev/fb0)截圖 # cat /dev/fb0 > frame.raw #apt-get install ffmpeg #ffmpeg -vcodec rawvideo -f rawvideo -pix_fmt bgr24 -s 320X

linuxpython滑鼠的移動點選操作

 http://blog.sina.com.cn/s/blog_60b45f230101kucn.html具體實現,使用外部庫PyMouse,使用pip可以直接下載 pip install pymouse安裝pymouse必須要xlib的支援,剛開始以為xlib僅僅是在win

用python實現元素的長

一.目標 瀏覽網頁的時候,看見哪個元素,就能擷取哪個元素當圖片,不管那個元素有多長   二.所用工具和第三方庫 python ,PIL,selenium pycharm 三.程式碼部分 長截圖整體思路: 1.獲取元素 2.移動,截圖,移動,截圖,直到抵達元素的底部 3.把截圖按照元素所在位置切割,

QT實現Linux Shell調用的幾種方法

nes running qprocess -o test main new rest ring 使用QProcess QThread ============================================ #include <QProcess&

linux實現nginx安裝實現端口區分,域名區分

方便 img per 修改配置文件 mpat 直接 exp reg 獨立 nginx是一款高性能的http服務器/反向代理服務器及電子郵件代理服務器. 官方網站: http://nginx.org/ 1、http服務器。Nginx是一個http服務可以獨立提供http服務。

Linux實現免密碼登錄(超詳細)_Linux_腳本之家

.html ini 服務 meta word ssh密鑰 密碼登錄 rda lin Linux ssh密鑰登錄和取消密鑰登錄 2016-05-18? linux技巧 ? 暫無評論 在VPS中利用vi編輯器編輯sshd的配置文件 vi /etc/ssh/sshd_conf

[科技]NOI Linux拍程序

ima 而是 cst 裏的 aps 環境 輸入 函數 mage 我們知道,在$Windows$環境下用$cmd$裏的$FC$函數實現對拍(放到一個目錄下): #include <cstdlib> int main(){ while(true){

Linux實現多網卡綁定

bond team nmctl 使用bind綁定多個網卡 由於服務器上對於可用性的要求都比較高,對於各項功能都會有有冗余設計,比如,磁盤、電源、網卡、甚至服務器本身等等,今天嘗試做一下網卡綁定實現網卡的冗余。網卡綁定的實現表面上看起來有些像是硬盤實現邏輯卷,都是通過創建一個邏輯設備來實現的。實現網

linux實現目錄即文件的完整刪除

truct remove define limits In continue tin mit ret 功能:   1、刪除目錄   2、刪除文件   3、刪除不為空的目錄即下屬文件 #ifndef _DELETE_FILE #define _DELETE_FILE #in

linux實現ssh免密登錄

復制 由於 linu width tro watermark linux roc 密碼登錄 設置ssh無密碼登錄可以提高我們主機的安全性。ssh 無密碼登錄要使用公鑰與私鑰。linux下可以用ssh-keygen生成公鑰/私鑰對,接下來以Centos為例。例圖:實驗主機A無

記錄linux通過limits的設置來優化系統性能

pgrep 目前 接下來 total 滿足 執行 獲取 linux下 第一個 系統中子進程繼承父進程的系統限制。只有以root用戶運行的進程能任意修改限制。其它進程不能增加硬限制值。這樣在一個session中登錄進程設置的硬限制值影響該session中的所有進程。 當要優化

Linux實現彩色進度條程式

程式碼: #include <stdio.h> #include <unistd.h> #include <string.h> int main() { int i = 0; char bar[101]; const char *la

Linux實現指令碼監測特定程序佔用記憶體情況

記憶體洩露是C/C++程式設計師經常需要面對的問題,除了有效地經常查找出記憶體洩露的位置外,在嵌入式的開發中,還經常需要確定自己寫的程式是否存在記憶體洩露的情況 Linux系統下,我們可以利用以下命令來獲取特定程序的執行情況: cat /proc/$PID/status 其中

Linux實現客戶端兩連跳ping百度,修改dns和nmcil的用法

1.客戶端跳兩次路由器ping百度 rht vmctl reset 重置虛擬機器 真機和虛擬機器開啟火牆策略 用在配置網路單元學的修改兩機閘道器 設定server為雙網絡卡路由端接觸客戶端Desktop閘道器為1.1.1.100 路由器端設定GATEWAY為真機,記得syste

Linux實現進度條程式. 通過makefile進行編譯. 建議自主完成一個彩色的進度條.

Linux下用C語言完成一個彩色進度條 1.建一個Makefile檔案 2.vim Makefile test:test.c

Linux實現腳本監測特定進程占用內存情況

date 信息 進程pid -s 虛擬內存 狀況 文件 python 完整 Linux系統下,我們可以利用以下命令來獲取特定進程的運行情況: cat /proc/$PID/status 其中PID是具體的進程號,這個命令打印出/proc/特定進程/status文件的內

Linux實現Mysql定時任務備份資料

建立備份目錄 本例項將建立目錄放置於/mnt目錄下,可根據具體情況放置於其他目錄: cd /mnt mkdir dbback pwd /mnt/dbback 建立shell指令碼 指令碼名稱可根據自己規範進行自定義: vim bcmysql.sh 進入編輯器

Linux實現 MySQL 數據庫定時自動備份

用戶 itl 安裝 centos fin nta 腳本 apach 例子 Linux 下如何實現 MySQL 數據庫定時自動備份? 概述

Linux實現最常用的磁碟陣列RAID5

(一) RAID簡介:獨立磁碟冗餘陣列(RAID, Redundant Array of Independent Disks),舊稱廉價磁碟冗餘陣列(RAID,Redundant Array of Inexpensive Disks),簡稱硬碟陣列。其基本思想就是把多個相對便宜的硬碟組合起來,成為一個硬碟陣列