linux下怎么用c语言获取一帧屏幕图像数据,怎么分块

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux下怎么用c语言获取一帧屏幕图像数据,怎么分块相关的知识,希望对你有一定的参考价值。

1. 利用FrameBuffer设备,用ioctl()函数获取相关屏幕信息,然后用mmap()映射,用两个for循环逐个读取
for (y = 0; y < scrinfo.yres; y++)
for (x = 0; x < scrinfo.xres; x++)
获取一帧屏幕图像数据有没有更简洁方便的方法?

2. 把屏幕图像分成4×4或16×16的块。关于这方面的网上的都是一带而过,没说具体怎么分块,怎么保存像素数据。最近在学习linux下的桌面共享,求大神指点,急

教你一个方法,你想找某个方面的资源,就在关键词后面加详解两个字,通常都能搜到。例如搜

FrameBuffer详解
就能得到你要的东西了。

至于图像分块嘛,自己用memcpy把buffer里的图像拷贝出来,自己手动写循环分块啦。分4块那就拷贝到4个内存块里啦,写的时候注意循环的下标就行了。追问

FrameBuffer了解得还行,主要是怎么分块存储像素数据(包括块号标记),还要考虑屏幕宽和高能不能被16整除,看了一些资料有点儿头绪但还是比较乱,如果这里解决了下面就比较容易进行了。可否再指点一下?

追答

struct buffer_block
int block_id; //存块id

char* data; //存储数据

int width;

int height;

;
height = scrinfo.yres/4

width = scrinfo.xres/4
先计算得width和height,再分配空间
data = malloc(width*height*4);
然后把framebuffer的数据复制到data中

一共复制16次,得到16个buffer_block。

要分16块的话,屏幕宽和高能被4整除就行了,不是被16整除。如果不能被4整除,那么就取最邻近的值。比如图像是 400x250,那么你可以在图像的边缘添加像素,添加成400x256像素的图像。

追问

字数有限,只能截图…… 

这个复制数据的写法对吗

追答

先要算出每一个小块的width, height

width = fb->width/4;
height = fb->height/4;
p->data 要先分配空间,然后才能memcpy,结束之后还要释放空间。
size = width*height;
p->data = (unsigned char*)malloc(size);

这段代码逻辑基本上是对了,细节上可能还要调试一下,自己上机编译实验一下吧。

参考技术A

    如果已经映射了的话,理论上应该是直接可以memcpy的,这个方法你可以尝试一下

    图像分块其实很简单,帧数据说白了就是一个很大的数组,你可以理解为二维数组

    对二维数组进行切分很简单吧。

追问

由于后面要比较两个对应块的帧数据,分块的同时要记录该块号,这时候怎么存储块号和帧数据。

这是网上找到的大概方法,可是还是不懂,Bmp若是数组的话那岂不是最多有15个数据?怎么做到根据块号比较两块的数据,知道的话可否详细说一下

追答

上面的这段代码我表示不知道是什么语言,即像c语言,但是如果按c的语法来判断完全都是些错误的代码所以不做评论,划分数据块可以通过结构体来实现例如
struct Chunk_data

int flag; //读写标志

int frame_num; //块号

char frame_data[16*16];//块大小
chunk_data;

比较两块数据,有很多种方法你可以直接调用strcmp也可以自己构建一个,但是效率如何还是要自己去尝试

追问

这个只是存储一个块的数据与块号,由于结构体不像数组那样,要存储所有块的 是不是要用链表来存储呢
struct Chunk_data

int flag; //读写标志

int frame_num; //块号

char frame_data[16*16];//块大小
Chunk_data *next;
chunk_data;

追答

用链表有链表的好处,如果熟悉链表的话,使用链表还好一点,如果不熟悉的话可以用结构体数组
其实两个本质上的区别不是很大

linux下c语言的crypt函数怎么用?

linux的crypt

最近学校布置了一个网安的小作业,要用到linux里面的这个crypt函数,写一篇总结一下。首先我们要了解这个函数是用来做什么的。

密码影子文件中存储了每一个用户的用户明文和其单向哈希过的秘文

cipher = "$1$C68vnJ27$1ttFZ1/Rylq/xi350A0NI0";

密码字段用\\(id\\)salt$hashed的格式存储,其中id字段是1,salt是C68vnJ27,hash为1ttFZ1/Rylq/xi350A0NI0

其中$id表示计算密码密文所用的哈希算法,对应关系如下:

  • $1$ 表示 MD5
  • $5$ 表示 SHA-256
  • $6$ 表示 SHA-512
  • $2a$$2y$表示Blowfish算法

那这个由明文加密的过就是由crypt()函数完成的,crypt()是一个密码加密函数(将密码加密,明文变成密文),该函数基于数据加密标准(DES,Data Encryption Standard )算法以及基于DES的其他变种算法,该函数不依赖于计算机硬件实现数据加密。DES算法仅适合于加密字符串,也就是用于生成密码。尽管密码的生成有很多种方法。

salt的定义是在密码学中,是指通过在密码任意固定位置插入特定的字符串,让散列后的结果和使用原始密码的散列结果不相符,这种过程称之为“加盐”。Salt 可以是任意字母、数字、或是字母或数字的组合,但必须是随机产生的,每个用户的 Salt 都不一样,用户注册的时候,数据库中存入的不是明文密码,也不是简单的对明文密码进行散列,而是 MD5( 明文密码 + Salt)。salt是一种混淆key的一段范围在abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./中的“随机”字符串,具体最小长度和最大长度根据加密方法的不同而不同。

官方给出的crypt的用法是要传入一个密钥和一个salt,这个密钥就是用户密码。在编译c语言文件时,我们主要写成"gcc -o crypt crypt.c -lcrypt"去调用crypt这个库

现在题目给出了12位密钥中的前五位和后两位,中间5个都是数字,我们可以使用爆破的方式去实现一下crypt方法。

直接给出代码

```c
//
// Created by ivanlee on 2023/3/26.
//
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <crypt.h>

const char* ans_cipher = "$1$XwynSv0a$qgSbP2GtPyeEyq6ZVWPUZ1";
const char* first5 = "*CMS";
const char* last2 = "c#";
const char* salt = "$1$XwynSv0a$";

int main(int argc, char* argv[])
    for(int a=0; a<10;a++)
        char str[30];
        strcpy(str,first5);
        char tmpa;
        tmpa = \'0\' + a;
        str[5] = tmpa;
        for(int b=0; b<10;b++)
            char tmpb;
            tmpb = \'0\' + b;
            str[6] = tmpb;
            for(int c=0; c<10;c++)
                char tmpc;
                tmpc = \'0\' + c;
                str[7] = tmpc;
                for(int d=0; d<10;d++)
                    char tmpd;
                    tmpd = \'0\' + d;
                    str[8] = tmpd;
                    for(int e=0; e<10;e++)
                        char tmpe;
                        tmpe = \'0\'+e;
                        str[9]=tmpe;
                        str[10]=\'c\';
                        str[11]=\'#\';
                        char cipher[50];
                        char new[12];
                        strncpy(new,str,12);
                        strcpy(cipher,crypt(new,salt));
                        if(strcmp(cipher,ans_cipher)==0) 
                            printf("the ans is: %s\\n", new);
                            return 0;
                        

                    
                
            
        
    
    return 0;


主要当我们了解了盐是什么,crypt是怎么加密的,这个判断爆破密码的很简单了,从00000开始到99999依次拼接进去进行加密,半分钟左右就爆出密码了

以上是关于linux下怎么用c语言获取一帧屏幕图像数据,怎么分块的主要内容,如果未能解决你的问题,请参考以下文章

C语言怎么截屏并将数据转换成RGB或YUV420

Linux系统的C语言怎么清屏?

用VC++如何获取屏幕图像,且显示出来

linux下怎么用纯c语言连接mongodb数据库进行读写操作

请问,linux下C/C++怎么获取屏幕分辨率?(不使用Qt和GTK)

请问怎么用c语言获取电脑(windows)的cpu,内存,硬盘利用率等信息?Linux系统一样吗?