DSP

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

2019-07-13 15:32发布

环境: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图像的蓝 {MOD}和红 {MOD}分量  * 参数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 temp = buffer[i]; buffer[i] = buffer[i+2]; buffer[i+2] = temp; } } }