前言
在QNX中原生系统提供了screenshot的shell指令,但是指令提供的可操作内容较少,所以基于QNX screenshot的指令原理,实现了一种控制性强、控制权限高、控制范围广的一个screenshot程序。
QNX原生screenshot使用方法
QNX提供的原生的screenshot程序是一个命令行工具,用于从显示器中捕获内容。成功捕获内容后,屏幕截图会将捕获的内容以位图格式保存在指定的文件路径中。
QNX原生screenshot使用方法:
screenshot [-display=display_id]
[-file=output_file]
[-size=widthxheight]
-display=display_id
将显示器ID(整数)或连接类型(字符串)设置为显示器。如果您提供了一个整数,Screen会将该整数解释为显示标识符的指示。否则,如果提供字符串,Screen会将该字符串解释为显示连接类型。显示端口的连接类型可以是以下字符串之一:
internal、composite、svideo、YPbPr、rgb、rgbhv、dvi、hdmi
-file=output_file
指定屏幕截图的文件路径。如果未指定此选项,则输出将存储在screenshot.bmp中。
-size=widthxheight
使用宽度和高度的整数值设置屏幕截图的大小(默认为全屏)。
自研screenshot程序
自研screenshot提供了更多的输出文件的控制权限,并且对输出的bmp位图也有控制方法,可根据实际使用需求进行调整。
qnxwindow.h
#ifndef _QNXWINDOW_H_
#define _QNXWINDOW_H_
#include<screen/screen.h>
#pragma pack(push, 2)//强制两字节对齐
typedef struct bitmap_info_header
{
uint32_t biSize; /* Size of info header */
uint32_t biWidth; /* Width of image */
uint32_t biHeight; /* Height of image */
uint16_t biPlanes; /* Number of color planes */
uint16_t biBitCount; /* Number of bits per pixel */
uint32_t biCompression; /* Type of compression to use */
uint32_t biSizeImage; /* Size of image data */
uint32_t biXPelsPerMeter; /* X pixels per meter */
uint32_t biYPelsPerMeter; /* Y pixels per meter */
uint32_t biClrUsed; /* Number of colors used */
uint32_t biClrImportant; /* Number of important colors */
}bitmap_info_header_t;
typedef struct bitmap_header
{
uint16_t bfType; /*bmp=0x4D42*/
uint32_t bfSize; /* Size of file */
uint16_t bfReserved1; /* Reserved */
uint16_t bfReserved2; /* ... */
uint32_t bfOffBits; /* Offset to bitmap data */
bitmap_info_header_t bitmap_info;
} bitmap_header_t;
class QNXWindow
{
private:
/* data */
public:
QNXWindow();
~QNXWindow();
void create_screenshot_bmp();
};
#endif
qnxwindow.cpp
#include"qnxwindow.h"
#include<iostream>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<thread>
#define DISPLAY_SCREEN 0
#define DISPLAY_WIDTH 1920
#define DISPLAY_HEIGHT 720
QNXWindow::QNXWindow()
{
create_screenshot_bmp();
}
QNXWindow::~QNXWindow()
{
}
void QNXWindow::create_screenshot_bmp()
{
screen_context_t screen_bmp_ctx;
screen_create_context(&screen_bmp_ctx, SCREEN_DISPLAY_MANAGER_CONTEXT);
//获取显示屏幕的数量
int count = 0;
screen_get_context_property_iv(screen_bmp_ctx, SCREEN_PROPERTY_DISPLAY_COUNT, &count);
screen_display_t *screen_displays = (screen_display_t*)calloc(count, sizeof(screen_display_t));
screen_get_context_property_pv(screen_bmp_ctx, SCREEN_PROPERTY_DISPLAYS, (void**)screen_displays);
for(int i = 0; i < count; ++i)
{
//读取屏幕信息
int display_id;
int size[2];
screen_get_display_property_iv(screen_displays[i], SCREEN_PROPERTY_ID, &display_id);
screen_get_display_property_iv(screen_displays[i], SCREEN_PROPERTY_SIZE, size);
printf("screen_pixmap = %d, width = %d, height = %d\n", display_id, size[0], size[1]);
}
screen_pixmap_t screen_pixmap = nullptr;
screen_buffer_t screen_pixmap_buf = nullptr;
char *screen_pixmap_ptr = nullptr;
int screen_pixmap_stride = 0;
int rect[4] = { 0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT};
screen_create_pixmap(&screen_pixmap, screen_bmp_ctx);
int usage = SCREEN_USAGE_READ | SCREEN_USAGE_NATIVE ;
screen_set_pixmap_property_iv(screen_pixmap, SCREEN_PROPERTY_USAGE, &usage);
int format = SCREEN_FORMAT_RGBA8888;
screen_set_pixmap_property_iv(screen_pixmap, SCREEN_PROPERTY_FORMAT, &format);
//set the buffer size of the pixmap
int size[2] = {DISPLAY_WIDTH, DISPLAY_HEIGHT};
screen_set_pixmap_property_iv(screen_pixmap, SCREEN_PROPERTY_BUFFER_SIZE, size);
//create the pixmap buffer
//the buffer where the pixels from the source window will be copied to
screen_create_pixmap_buffer(screen_pixmap);
screen_get_pixmap_property_pv(screen_pixmap, SCREEN_PROPERTY_RENDER_BUFFERS, (void**)&screen_pixmap_buf);
screen_get_buffer_property_pv(screen_pixmap_buf, SCREEN_PROPERTY_POINTER, (void**)&screen_pixmap_ptr);
screen_get_buffer_property_iv(screen_pixmap_buf, SCREEN_PROPERTY_STRIDE, &screen_pixmap_stride);
//take the window screenshot
screen_read_display(screen_displays[DISPLAY_SCREEN], screen_pixmap_buf, 0, NULL, 0);
if(screen_displays == nullptr)
{
printf("get disp failed!\n");
return;
}
int length = sizeof(bitmap_header_t);
bitmap_header_t bitmap_head;
bitmap_head.bfType = 0x4D42;//文件类型
bitmap_head.bfSize = DISPLAY_WIDTH * DISPLAY_HEIGHT * 4;//文件数据长度
bitmap_head.bfReserved1 = 0;
bitmap_head.bfReserved2 = 0;
bitmap_head.bfOffBits = 0x36;
bitmap_head.bitmap_info.biSize = sizeof(bitmap_info_header_t);//图像数据头大小
bitmap_head.bitmap_info.biWidth = DISPLAY_WIDTH;
bitmap_head.bitmap_info.biHeight = DISPLAY_HEIGHT;
bitmap_head.bitmap_info.biPlanes = 1;
bitmap_head.bitmap_info.biBitCount = 32;
bitmap_head.bitmap_info.biCompression = 0;
bitmap_head.bitmap_info.biSizeImage = 0;
bitmap_head.bitmap_info.biXPelsPerMeter = 5000;
bitmap_head.bitmap_info.biYPelsPerMeter = 5000;
bitmap_head.bitmap_info.biClrUsed = 0;
bitmap_head.bitmap_info.biClrImportant = 0;
int nbytes = size[0] * size[1] * 4;
std::string fname = "/screenpixmap.bmp";
int fd = creat(fname.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
write(fd, &bitmap_head, length);
printf("size = %d\n", length);
printf("screen_pixmap_ptr = %p\n", screen_pixmap_ptr);
printf("screen_pixmap_stride = %d\n", screen_pixmap_stride);
/*bmp显示顺序与写入顺序相反*/
for(int i = size[1] - 1; i >= 0; i--)
{
write(fd, screen_pixmap_ptr + i * screen_pixmap_stride, size[0] * 4);
}
close(fd);
printf("finished!\n");
}