Linux下framebuffer保存为BMP

转自: https://blog.csdn.net/gp_scoprius/article/details/53787630

在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 说明从文件头开始到实际的图象数据之间的字节的偏移量。这个参数是非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,所以你可以用这个偏移值迅速的从文件中读取到位数据。
位图信息段内容如下:


    
    
  1. DWORD biSize;
  2. LONG biWidth;
  3. LONG biHeight;
  4. WORD biPlanes;
  5. WORD biBitCount
  6. DWORD biCompression;
  7. DWORD biSizeImage;
  8. LONG biXPelsPerMeter;
  9. LONG biYPelsPerMeter;
  10. DWORD biClrUsed;
  11. 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.

实现代码如下:


    
    
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <sys/ioctl.h>
  5. #include <sys/soundcard.h>
  6. #include <stdio.h>
  7. #include <unistd.h>
  8. #include <math.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. static unsigned char sg_BHeader[] = {
  12. 0x42, 0x4D, 0x36, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
  13. 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
  14. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  15. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  16. };
  17. #define RGB565TO1555(rgb) ((unsigned short)((unsigned short)(rgb & 0x001f) | ((unsigned short)(rgb & 0xffc0) >> 1)))
  18. void SaveBMPFile(unsigned char *raw, char *filename)
  19. {
  20. unsigned short *p = ( unsigned short *)raw;
  21. typedef unsigned int UINT;
  22. typedef unsigned char UCHAR;
  23. UINT m_Width = 800, m_Height = 480;
  24. UINT i, j;
  25. int bmp = open(filename, O_WRONLY | O_CREAT);
  26. if(bmp < 0)
  27. return;
  28. sg_BHeader[ 0x02] = (UCHAR)(m_Width * m_Height * 2 + 0x36) & 0xff;
  29. sg_BHeader[ 0x03] = (UCHAR)((m_Width * m_Height * 2 + 0x36) >> 8) & 0xff;
  30. sg_BHeader[ 0x04] = (UCHAR)((m_Width * m_Height * 2 + 0x36) >> 16) & 0xff;
  31. sg_BHeader[ 0x05] = (UCHAR)((m_Width * m_Height * 2 + 0x36) >> 24) & 0xff;
  32. sg_BHeader[ 0x12] = (UCHAR)m_Width & 0xff;
  33. sg_BHeader[ 0x13] = (UCHAR)(m_Width >> 8) & 0xff;
  34. sg_BHeader[ 0x14] = (UCHAR)(m_Width >> 16) & 0xff;
  35. sg_BHeader[ 0x15] = (UCHAR)(m_Width >> 24) & 0xff;
  36. sg_BHeader[ 0x16] = (UCHAR)m_Height & 0xff;
  37. sg_BHeader[ 0x17] = (UCHAR)(m_Height >> 8) & 0xff;
  38. sg_BHeader[ 0x18] = (UCHAR)(m_Height >> 16) & 0xff;
  39. sg_BHeader[ 0x19] = (UCHAR)(m_Height >> 24) & 0xff;
  40. write(bmp, sg_BHeader, sizeof(sg_BHeader));
  41. for(i = 0; i < m_Height; i++)
  42. {
  43. unsigned short *c = p + (m_Height - 1 - i) * m_Width;
  44. unsigned short cc;
  45. for(j = 0; j < m_Width; j++)
  46. {
  47. cc = RGB565TO1555(*(c + j));
  48. // cc = *(c + j);
  49. write(bmp, &cc, 2);
  50. }
  51. }
  52. close(bmp);
  53. }
  54. int main(int argc, char *argv[])
  55. {
  56. unsigned char buf[ 800* 480* 2];
  57. char *filename;
  58. int fb;
  59. fb = open( "/dev/fb0", O_RDONLY);
  60. if(fb < 0)
  61. exit( 1);
  62. if(argc == 2)
  63. filename = argv[ 1];
  64. else
  65. exit( 1);
  66. printf( "reading screen...\n");
  67. read(fb, buf, 800* 480* 2);
  68. close(fb);
  69. printf( "saving screen...\n");
  70. SaveBMPFile(buf, filename);
  71. printf( "file %s created successfully\n", filename);
  72. exit( 0);
  73. }
            </div>

在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 说明从文件头开始到实际的图象数据之间的字节的偏移量。这个参数是非常有用的,因为位图信息头和调色板的长度会根据不同情况而变化,所以你可以用这个偏移值迅速的从文件中读取到位数据。
位图信息段内容如下:


  
  
  1. DWORD biSize;
  2. LONG biWidth;
  3. LONG biHeight;
  4. WORD biPlanes;
  5. WORD biBitCount
  6. DWORD biCompression;
  7. DWORD biSizeImage;
  8. LONG biXPelsPerMeter;
  9. LONG biYPelsPerMeter;
  10. DWORD biClrUsed;
  11. 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.

实现代码如下:


  
  
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <sys/ioctl.h>
  5. #include <sys/soundcard.h>
  6. #include <stdio.h>
  7. #include <unistd.h>
  8. #include <math.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. static unsigned char sg_BHeader[] = {
  12. 0x42, 0x4D, 0x36, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
  13. 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
  14. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  15. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  16. };
  17. #define RGB565TO1555(rgb) ((unsigned short)((unsigned short)(rgb & 0x001f) | ((unsigned short)(rgb & 0xffc0) >> 1)))
  18. void SaveBMPFile(unsigned char *raw, char *filename)
  19. {
  20. unsigned short *p = ( unsigned short *)raw;
  21. typedef unsigned int UINT;
  22. typedef unsigned char UCHAR;
  23. UINT m_Width = 800, m_Height = 480;
  24. UINT i, j;
  25. int bmp = open(filename, O_WRONLY | O_CREAT);
  26. if(bmp < 0)
  27. return;
  28. sg_BHeader[ 0x02] = (UCHAR)(m_Width * m_Height * 2 + 0x36) & 0xff;
  29. sg_BHeader[ 0x03] = (UCHAR)((m_Width * m_Height * 2 + 0x36) >> 8) & 0xff;
  30. sg_BHeader[ 0x04] = (UCHAR)((m_Width * m_Height * 2 + 0x36) >> 16) & 0xff;
  31. sg_BHeader[ 0x05] = (UCHAR)((m_Width * m_Height * 2 + 0x36) >> 24) & 0xff;
  32. sg_BHeader[ 0x12] = (UCHAR)m_Width & 0xff;
  33. sg_BHeader[ 0x13] = (UCHAR)(m_Width >> 8) & 0xff;
  34. sg_BHeader[ 0x14] = (UCHAR)(m_Width >> 16) & 0xff;
  35. sg_BHeader[ 0x15] = (UCHAR)(m_Width >> 24) & 0xff;
  36. sg_BHeader[ 0x16] = (UCHAR)m_Height & 0xff;
  37. sg_BHeader[ 0x17] = (UCHAR)(m_Height >> 8) & 0xff;
  38. sg_BHeader[ 0x18] = (UCHAR)(m_Height >> 16) & 0xff;
  39. sg_BHeader[ 0x19] = (UCHAR)(m_Height >> 24) & 0xff;
  40. write(bmp, sg_BHeader, sizeof(sg_BHeader));
  41. for(i = 0; i < m_Height; i++)
  42. {
  43. unsigned short *c = p + (m_Height - 1 - i) * m_Width;
  44. unsigned short cc;
  45. for(j = 0; j < m_Width; j++)
  46. {
  47. cc = RGB565TO1555(*(c + j));
  48. // cc = *(c + j);
  49. write(bmp, &cc, 2);
  50. }
  51. }
  52. close(bmp);
  53. }
  54. int main(int argc, char *argv[])
  55. {
  56. unsigned char buf[ 800* 480* 2];
  57. char *filename;
  58. int fb;
  59. fb = open( "/dev/fb0", O_RDONLY);
  60. if(fb < 0)
  61. exit( 1);
  62. if(argc == 2)
  63. filename = argv[ 1];
  64. else
  65. exit( 1);
  66. printf( "reading screen...\n");
  67. read(fb, buf, 800* 480* 2);
  68. close(fb);
  69. printf( "saving screen...\n");
  70. SaveBMPFile(buf, filename);
  71. printf( "file %s created successfully\n", filename);
  72. exit( 0);
  73. }
            </div>

猜你喜欢

转载自blog.csdn.net/abc3240660/article/details/81668249
今日推荐