framebuffer 截屏程序

1、本程序使用到jpeg库,请读者自行安装

2、废话少说,上源码。

#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>

#define FBDEV         ( "/dev/fb0" )
#define FBTMPDEV      ( "/tmp/fb0" )
/* RGB565转RGB888函数
*@rgb565: 指向存放rgb565数据的起始地址
*@rgb24:指向存放rgb24数据的起始地址
*@width:屏幕(分辨率)的宽度
*@height:屏幕(分辨率)的高度
*/
int RGB565_to_RGB888( unsigned char* rgb565, unsigned char* rgb24, int width, int height )
{
    int i = 0;
    int whole = width * height;
    unsigned char r, g, b;
    unsigned short int* pix565 = NULL;
    
    if ( NULL == rgb565 || NULL == rgb24 || width < 0 || height < 0 )
    {
        return  -1;
    }
    
    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 0;
}

/* jpeg压缩函数
*@filename:jpg文件名
*@rgb:指向存放rgb24数据的起始地址
*@width:屏幕(分辨率)的宽度
*@height:屏幕(分辨率)的高度
*@quality: jpeg压缩质量
*/
int Jpeg_Compress(const char* filename, unsigned char* rgb, int width, int height, int quality )
{
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    FILE* outfile = NULL;
    JSAMPROW row_pointer[ 1 ];
    int row_stride = 0;
    
    if ( NULL == filename || NULL == rgb || width < 0 || height < 0 || quality < 0 )
    {
        return -2;
    }
    cinfo.err = jpeg_std_error( &jerr );
    jpeg_create_compress( &cinfo );
    //输出文件
    outfile = fopen( filename, "wb" );
    if ( outfile == NULL )
    {
        return -1;
    }
    jpeg_stdio_dest( &cinfo, outfile );

    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = 3;
    //输入数据格式为RGB
    cinfo.in_color_space = JCS_RGB;

    jpeg_set_defaults( &cinfo );
    //压缩质量
    jpeg_set_quality( &cinfo, quality, TRUE );
    jpeg_start_compress( &cinfo, TRUE );
    row_stride = width * 3;

    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 0;
}

/* 截图函数
*@filename:jpg文件名
*/
int Cut_ScreenFun( const char* filename )
{
    int fd = -1;
    int fdOne = -1;
    struct fb_var_screeninfo fb_var_info;
    unsigned char* trgb = NULL;
    unsigned char* rgb = NULL;
    int buffer_size = 0;
    int return_value = 0;
    
    if ( NULL == filename )
    {
        return_value = -1;
        return return_value;
    }
    
    system("cat /dev/fb0 > /tmp/fb0");
    fdOne = open( FBTMPDEV, O_RDONLY );
    if ( fdOne < 0 )
    {
        printf( "can not open tmp dev\n" );
        return_value = -2;
        goto open_tmp;        
    }
    //打开framebuffer设备
    fd = open( FBDEV, O_RDONLY );
    if ( fd < 0 )
    {
        printf( "can not open dev\n" );
        return_value = -2;
        goto open_tmp;
    }

    //获取LCD的可变参数
    ioctl( fd, FBIOGET_VSCREENINFO, &fb_var_info );

    //一帧大小
    buffer_size = ( ( fb_var_info.xres * fb_var_info.yres * fb_var_info.bits_per_pixel ) >> 3 );

    trgb = ( unsigned char* )malloc( buffer_size );
    if ( NULL == trgb )
    {
        return_value = -3;
        goto here;
    }
    rgb = ( unsigned char* )malloc( fb_var_info.xres * fb_var_info.yres * 3 );
    if ( NULL == rgb )
    {
        return_value = -4;
        goto here;
    }
    //获取一帧数据
    if ( read ( fdOne, trgb, buffer_size ) < 0 )
    {
        printf( "read failed!\n" );
        return_value = -5;
        goto read_fail;
    }
    //格式转换
    if ( RGB565_to_RGB888( trgb, rgb, fb_var_info.xres, fb_var_info.yres ) < 0 )
    {
        printf( "call RGB565_to_RGB888 failed!\n" );
        return_value = -6;
        goto read_fail;
    }
    //jpeg压缩
    if ( Jpeg_Compress( filename, rgb, fb_var_info.xres, fb_var_info.yres, 80 ) < 0 )
    {
        printf( "compress failed!\n" );
        return_value = -7;
        goto read_fail;
    }        
    
read_fail:
    free( rgb );
here:
    free( trgb );
    close( fd );
    close( fdOne );
open_tmp:
    unlink( FBTMPDEV );
    return return_value;        
}

int main( void )
{
    Cut_ScreenFun( "./gn1108.jpg" );
    system( "chmod a+x gn1108.jpg" );
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值