2019-07-10

                                                                                                     工作日志:QNX截屏与黑屏判断

截屏原理:通过捕获屏幕数据,将数据写入BMP文件,生成一张BMP位图。

黑屏判断原理:遍历捕获屏幕的RBG值,如果RGB为(0,0,0),说明都是黑色,那么就是黑屏。本代码捕获的是32bit数据,分别是A R G B(阿尔法透明度、红、绿、蓝),每项各一个字节,所以是32bit。然后循环遍历RGB的值,也可以将数据写入BMP文件后再打开BMP文件在去读RGB也可以,本文是在写BMP之前遍历数据的。

此书省略.h声明

void CScreenShot::WriteBitmapHeader(int nbytes, int fd, const int size[])

{   //写BMP文件头

char header[54];

/* Set standard bitmap header */

header[0] = 'B';

header[1] = 'M';

header[2] = nbytes & 0xff;

header[3] = (nbytes >> 8) & 0xff;

header[4] = (nbytes >> 16) & 0xff;

header[5] = (nbytes >> 24) & 0xff;

header[6] = 0;

header[7] = 0;

header[8] = 0;

header[9] = 0;

header[10] = 54;

header[11] = 0;

header[12] = 0;

header[13] = 0;

header[14] = 40;

header[15] = 0;

header[16] = 0;

header[17] = 0;

header[18] = size[0] & 0xff;

header[19] = (size[0] >> 8) & 0xff;

header[20] = (size[0] >> 16) & 0xff;

header[21] = (size[0] >> 24) & 0xff;

header[22] = -size[1] & 0xff;

header[23] = (-size[1] >> 8) & 0xff;

header[24] = (-size[1] >> 16) & 0xff;

header[25] = (-size[1] >> 24) & 0xff;

header[26] = 1;

header[27] = 0;

header[28] = 32;

header[29] = 0;

header[30] = 0;

header[31] = 0;

header[32] = 0;

header[33] = 0;

header[34] = 0; /* image size*/

header[35] = 0;

header[36] = 0;

header[37] = 0;

header[38] = 0x9;

header[39] = 0x88;

header[40] = 0;

header[41] = 0;

header[42] = 0x9l;

header[43] = 0x88;

header[44] = 0;

header[45] = 0;

header[46] = 0;

header[47] = 0;

header[48] = 0;

header[49] = 0;

header[50] = 0;

header[51] = 0;

header[52] = 0;

header[53] = 0;

/* Write bitmap header to file */

write(fd, header, sizeof(header));

}

void CScreenShot::WriteBitmapFile(const int size[], const char* screenshot_ptr,

                                                                                          const int screenshot_stride,

                                                                                          const BITMAP_FILE_PATH emFileIndex,

                                                                                          const bool bDetectScreen)

{

int nbytes; /* number of bytes of the bimap */

int fd; /* file descriptor */

int i; /* iterator to iterate over the screenshot buffer */

const char *fname = NULL; /* bitmap filename */

unsigned int *pScreenShotData = (unsigned int *)screenshot_ptr;

switch(emFileIndex)

{

case BM_BLACKSCREEN_PATH: fname = BM_BLACKSCREEN_PATH_; break;

case BM_LAMPMONITO_PATH: fname = BM_LAMPMONITO_PATH_; break;

default: fname = BM_BLACKSCREEN_PATH_; break;

}

/* Calculate the size of the bitmap */

nbytes = size[0] * size[1] * 4;

/* Perform this action only if you need to detect a black screen */

if(bDetectScreen)

{

for ( i = 0; i < nbytes / 4; i++ )

{

if ( pScreenShotData[i] & 0x00ffffff ) {

break;

}

}

/*Blank Screen*/

if ( i >= nbytes / 4 ) {

printf(" Program error, black screen detected\n");

}

    /*Normal screen display*/

else

{

// printf("BlackScreenDet : Screen display is normal ......................\n\n");

}

}

/* Open file*/

fd = creat(fname, S_IRUSR | S_IWUSR);

/* Write the standard bitmap header */

WriteBitmapHeader(nbytes, fd, size);

/* Write screenshot buffer contents to bitmap file */

/*  stride:  The number of pixels written horizontally one line at a time (x->1920 * 4)*/

for (i = 0; i < size[1]; i++) {

write(fd, screenshot_ptr + i * screenshot_stride, size[0] * 4);

}

close(fd);

}

int  CScreenShot::CaptureADisplayScreenShot(const BITMAP_FILE_PATH  emFileNameIndex, const bool  bDetectScreen)

{//截屏(基本上都是协同调用)

screen_context_t screen_ctx = NULL;

screen_display_t screen_disp = NULL;

screen_display_t *screen_displays = NULL;

screen_pixmap_t screen_pix = NULL;

screen_buffer_t screen_buf = NULL;

char *disp = NULL;

int size[2] = { 0, 0 };

int val;

void *pointer = NULL;

int stride;

int count, id, type;

//int i;

  /*创建screen上下文(关联设备的切入口)

  * 获取screen上下文显示器设备

  * 创建pixmap(像素图:屏幕当前显示的像素)

  * 将pixmap关联到内存(screen_buffer_t)

  * 获取内存的指针

  * screen_read_display()

  */

/* Create the privileged context so that the display properties can be accessed. */

screen_create_context(&screen_ctx, SCREEN_DISPLAY_MANAGER_CONTEXT);

/* Get the number of supported displays with this context. */

count = 0;

screen_get_context_property_iv(screen_ctx, SCREEN_PROPERTY_DISPLAY_COUNT,

                                    &count);

/* Get the displays for this context. */

if (count > 0) {

screen_displays = (screen_display_t*)calloc(count, sizeof(screen_display_t)); ////////////////change

screen_get_context_property_pv(screen_ctx, SCREEN_PROPERTY_DISPLAYS,

                                    (void **)screen_displays);

/* If no display was specified, use the first supported display available for this context. */

if (!disp) {

screen_disp = screen_displays[0];

//printf("run here\n");

/* Otherwise, determine which display has been requested for the screen shot. */

} /*else {

printf("run here else\n");

if (isdigit(*disp)) {

id = strtoul(disp, 0, NULL);

for (i = 0; i < count; i++) {

screen_get_display_property_iv(screen_displays[i], SCREEN_PROPERTY_ID,

                                    &val);

if (val == id) {

screen_disp = screen_displays[i];

break;

}

}

} else {

if (!strcmp(disp, "internal")) {

type = SCREEN_DISPLAY_TYPE_INTERNAL;

} else if (!strcmp(disp, "rgb")) {

type = SCREEN_DISPLAY_TYPE_COMPONENT_RGB;

} else if (!strcmp(disp, "dvi")) {

type = SCREEN_DISPLAY_TYPE_DVI;

} else if (!strcmp(disp, "hdmi")) {

type = SCREEN_DISPLAY_TYPE_HDMI;

} else {

type = SCREEN_DISPLAY_TYPE_OTHER;

}

for (i = 0; i < count; i++) {

screen_get_display_property_iv(screen_displays[i], SCREEN_PROPERTY_TYPE,

                                    &val);

if (val == type) {

screen_disp = screen_displays[i];

break;

}

}

}

}*/

free(screen_displays);

}

if (!screen_disp) {

fputs("no displays\n", stderr);

return 1;

}

/* Create pixmap for the screen shot. */

screen_create_pixmap(&screen_pix, screen_ctx);

/* Set usage flag. */

val = SCREEN_USAGE_READ | SCREEN_USAGE_NATIVE;

screen_set_pixmap_property_iv(screen_pix, SCREEN_PROPERTY_USAGE, &val);

/* Set format.  4 channel 32bit*/

val = SCREEN_FORMAT_RGBA8888;

screen_set_pixmap_property_iv(screen_pix, SCREEN_PROPERTY_FORMAT, &val);

/* If size is not specified, get the size from the display. */

if (size[0] <= 0 || size[1] <= 0) {

screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, size);

}

/* Set the pixmap buffer size. */

screen_set_pixmap_property_iv(screen_pix, SCREEN_PROPERTY_BUFFER_SIZE, size);

/* Create the pixmap buffer and get a handle to the buffer. */

screen_create_pixmap_buffer(screen_pix);

screen_get_pixmap_property_pv(screen_pix, SCREEN_PROPERTY_RENDER_BUFFERS,

                                  (void **)&screen_buf);

/* Get the pointer to the buffer. */

screen_get_buffer_property_pv(screen_buf, SCREEN_PROPERTY_POINTER, &pointer);

/* Get the stride. */

screen_get_buffer_property_iv(screen_buf, SCREEN_PROPERTY_STRIDE, &stride);

/* Take the display screen shot. */

screen_read_display(screen_disp, screen_buf, 0, NULL, 0);

/* Write the screenshot buffer to a bitmap file*/

WriteBitmapFile(size, (const char *)pointer, stride, emFileNameIndex, bDetectScreen);

/* Perform necessary clean-up. */

screen_destroy_pixmap(screen_pix);

screen_destroy_context(screen_ctx);

return 0;

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容