ubuntu下实现桌面截图并保存为png格式

环境:ubuntu12.10

这几天需要在ubuntu12.10下实现截取桌面图像并保存为png格式的文件,期间截屏的代码借鉴了http://bbs.csdn.net/topics/340056849处提供的方法。

保存为png借鉴了CxImage里面保存png的代码,经过大半天的测试,算是搞定了截屏保存为png格式的需求。

1、截屏的代码

int captureDesktop(const char* filename)

{

Window desktop;

Display* dap = NULL;

XImage* img = NULL;


int screen_width = 0;

int screen_height = 0;


dsp = XOpenDisplay(NULL);/* Connect to a local display */

if(NULL==dsp)

{

return 0;

}

desktop = RootWindow(dsp,0);/* Refer to the root window */

if(0==desktop)

{

return 0;

}


/* Retrive the width and the height of the screen */

screen_width = DisplayWidth(dsp,0);

screen_height = DisplayHeight(dsp,0);


/* Get the Image of the root window */

img = XGetImage(dsp,desktop,0,0,screen_width,screen_height,~0,ZPixmap);

if(img != NULL){

write_png(filename,img);

XDestroyImage(img);

}


XCloseDisplay(dsp);

return 1;

}


2、保存为png文件

/* Write a png file */

int write_png(const char *file_name ,XImage*image)

{

png_struct *png_ptr = NULL;

png_info *info_ptr = NULL;

FILE*fp = fopen(file_name,"wb+");


/* 分配并初始化png_struct数据结构(必须) */

png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,( void *)NULL,NULL,NULL);

if (png_ptr == NULL)

return -1;


/* 分配并初始化png_info数据结构(必须) */

info_ptr = png_create_info_struct(png_ptr);

if (info_ptr == NULL){

png_destroy_write_struct(&png_ptr,  (png_infopp)NULL);

return -1;

}


/* 设置输出控制 */

png_init_io(png_ptr, fp);


/* 设置文件信息 */

info_ptr->width = image->width;

info_ptr->height = image->height;

info_ptr->pixel_depth = (unsigned char)image->depth;

info_ptr->channels = (image->bits_per_pixel>8) ? (unsigned char)3: (unsigned char)1;

info_ptr->bit_depth = (unsigned char)(image->depth/info_ptr->channels);

info_ptr->compression_type = 0;

info_ptr->filter_type = 0;

info_ptr->valid = 0;


info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;

info_ptr->channels++;

info_ptr->bit_depth = 8;

info_ptr->pixel_depth += 8;


info_ptr->interlace_type = PNG_INTERLACE_NONE;


/* 设置最好压缩比 */

int compress_level = Z_BEST_COMPRESSION;

png_set_compression_level(png_ptr, compress_level);

//关键参数:WINDOWS上截图通常只有RGB,UBUNTU截图是RGBA,否则出来的图像显示不正传

info_ptr-> color_type = PNG_COLOR_TYPE_RGB_ALPHA;


/* 设置背景 */

png_color_16 image_background={ 0, 255, 255, 255, 0 };

png_set_bKGD(png_ptr, info_ptr, &image_background);


/* 设置尺寸 metrics */

png_set_IHDR(png_ptr, info_ptr, info_ptr->width, info_ptr->height, info_ptr->bit_depth,

info_ptr->color_type, info_ptr->interlace_type,

PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);


int row_size = image->bytes_per_line;

info_ptr->rowbytes = row_size;

unsigned char *row_pointers = new unsigned char[row_size];


/* 写文件信息 */

png_write_info(png_ptr, info_ptr);


//interlace handling

int num_pass = png_set_interlace_handling(png_ptr);

for (int pass = 0; pass < num_pass; pass++){

//写图像

int ay=0;

do {

memcpy(row_pointers,image->data+ay*4*image->width,row_size);

RGBtoBGR(row_pointers, row_size);

png_write_row(png_ptr, row_pointers);

ay++;

} while(ay<=(image->height-1));

}

       // 释放临时分配的内存

delete [] row_pointers;

row_pointers = NULL;


/* 写文件尾 (必须调用)*/

png_write_end(png_ptr, info_ptr);


/* 清除并释放分配的内存 */

png_destroy_write_struct(&png_ptr, (png_infopp)&info_ptr);


/* 关闭文件 */

if (fp != NULL){

fclose(fp);

fp = NULL;

}

return 0;

}


3、

/**

 * 交换RGB图像的蓝色和红色分量

 * 参数buffer : pointer to the pixels

 * 参数length : number of bytes to swap. lenght may not exceed the scan line.

 */

void RGBtoBGR(unsigned char *buffer, int length)

{

if (buffer != NULL){

unsigned char temp;

                //通常UBUNTU截图是4个字节表示一个像素(RGB+A)

for (int i=0;i<length;i+=4){

temp = buffer[i];

buffer[i] = buffer[i+2];

buffer[i+2] = temp;

}

}

}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值