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