2241431065 2022-01-04 15:36 采纳率: 50%
浏览 63
已结题

linux用C实现屏幕截图,网上参考到好多人使用这个代码,但是为什么自己运行就是黑屏?

生成执行文件,在crt里运行,生成图片是黑的?
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <malloc.h>
#include <linux/fb.h>
#include <jpeglib.h>
#include <jerror.h>
 
 
/*RGB565转RGB24函数
 *@rgb565: 指向存放rgb565数据的起始地址
 *@rgb24:指向存放rgb24数据的起始地址
 *@width:屏幕(分辨率)的宽度
 *@height:屏幕(分辨率)的高度
 */
int RGB565_to_RGB24(unsigned char *rgb565, unsigned char *rgb24, int width, int height)
{
    int i;
    int whole = width*height;
    unsigned char r, g, b;
    unsigned short int *pix565;
 
    pix565 = (unsigned short int *)rgb565;
 
    for(i = 0;i < whole;i++)
    {    
        r = ((*pix565)>>11)&0x1f;
        *rgb24 = (r<<3) | (r>>2);
        rgb24++;
        g = ((*pix565)>>5)&0x3f;
        *rgb24 = (g<<2) | (g>>4);
        rgb24++;
        b = (*pix565)&0x1f;
        *rgb24 = (b<<3) | (b>>2);
        rgb24++;
        pix565++;    
 
    }
    return 1;
}
 
/*jpeg压缩函数
 *@rgb:指向存放rgb24数据的起始地址
 *@width:屏幕(分辨率)的宽度
 *@height:屏幕(分辨率)的高度
*/
int jpeg_compress(unsigned char *rgb, int width, int height)
{
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    FILE * outfile;
    JSAMPROW row_pointer[1];
    int row_stride;
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    // 输出文件名为:out.jpg
    if ((outfile = fopen("out.jpg", "wb")) == NULL)
    {
        printf("can not open out.jpg\n");
        return -1;
    }
    jpeg_stdio_dest(&cinfo, outfile);
 
    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = 3;                // 1-灰度图,3-彩色图
    // 输入数据格式为RGB
    cinfo.in_color_space = JCS_RGB;            // JCS_GRAYSCALE-灰度图,JCS_RGB-彩色图
 
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, 80, TRUE);        // 设置压缩质量:80
    jpeg_start_compress(&cinfo, TRUE);        // 开始压缩过程
    row_stride = width * 3;                    // row_stride: 每一行的字节数
 
    while (cinfo.next_scanline < cinfo.image_height)
    {
        row_pointer[0] = &rgb[cinfo.next_scanline * row_stride];
        (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }
 
    jpeg_finish_compress(&cinfo);            // 完成压缩过程
    fclose(outfile);
 
    jpeg_destroy_compress(&cinfo);            // 释放资源
 
    return 1;
}
 
 
int main()
{
    int fd;
    struct fb_var_screeninfo fb_var_info;
    struct fb_fix_screeninfo fb_fix_info;
    unsigned char *trgb;
    unsigned char *rgb;
    int buffer_size;
 
    // 打开framebuffer设备
    fd = open("/dev/fb0", O_RDONLY);
    if(fd < 0)
    {
        printf("can not open dev\n");
        exit(1);
    }
 
    // 获取LCD的可变参数
    ioctl(fd, FBIOGET_VSCREENINFO, &fb_var_info);
    // 一个像素多少位    
    printf("bits_per_pixel: %d\n", fb_var_info.bits_per_pixel);
    // x分辨率
    printf("xres: %d\n", fb_var_info.xres);
    // y分辨率
    printf("yres: %d\n", fb_var_info.yres);
    // r分量长度(bit)
    printf("red_length: %d\n", fb_var_info.red.length);
    // g分量长度(bit)
    printf("green_length: %d\n", fb_var_info.green.length);
    // b分量长度(bit)
    printf("blue_length: %d\n", fb_var_info.blue.length);
    // t(透明度)分量长度(bit)
    printf("transp_length: %d\n", fb_var_info.transp.length);
    // r分量偏移
    printf("red_offset: %d\n", fb_var_info.red.offset);
    // g分量偏移
    printf("green_offset: %d\n", fb_var_info.green.offset);
    // b分量偏移
    printf("blue_offset: %d\n", fb_var_info.blue.offset);
    // t分量偏移
    printf("transp_offset: %d\n", fb_var_info.transp.offset);
 
    // 获取LCD的固定参数
    ioctl(fd, FBIOGET_FSCREENINFO, &fb_fix_info);
    // 一帧大小
    printf("smem_len: %d\n", fb_fix_info.smem_len);
    // 一行大小
    printf("line_length: %d\n", fb_fix_info.line_length);
    // 一帧大小
    buffer_size = (fb_var_info.xres * fb_var_info.yres * fb_var_info.bits_per_pixel / 8);
 
    trgb = (unsigned char *)malloc(buffer_size);
    if(trgb == NULL)
        exit(0);
    rgb = (unsigned char *)malloc(fb_var_info.xres * fb_var_info.yres * 3);
    if(rgb == NULL)
    {
        goto here;
    }
    if(read(fd, trgb, buffer_size) < 0)        // 获取一帧数据
    {
        printf("read failed!\n");
        goto read_fail;
    }
    // 格式转换
    RGB565_to_RGB24(trgb, rgb, fb_var_info.xres, fb_var_info.yres);
    // jpeg压缩
    if(jpeg_compress(rgb, fb_var_info.xres, fb_var_info.yres) < 0)
        printf("compress failed!\n");        
 
read_fail:
    free(rgb);
here:
    free(trgb);
 
    close(fd);
 
    return 0;
}

有人可以解惑一下吗?

  • 写回答

1条回答 默认 最新

  • qq_38219277 2022-01-08 14:35
    关注

    所获取到的内容是终端下的,不是图形显示界面下的内容,我也再找相关资料

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 1月18日
  • 已采纳回答 1月10日
  • 创建了问题 1月4日

悬赏问题

  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line