分类: LINUX
2009-04-29 11:13:38
9261EK上截取LCD上的图保存为jpeg图像
将程序编译之后下载到开发板上如下格式运行即可将LCD当前的显示存储为picc.jpg,将其上传到PC上既可看到效果。
./cutpic picc.jpg
其它编译等问题可以参考本博客的另一篇文章《9261EK上显示jpeg图片》
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define FB_DEV "/dev/fb0"
/***************** function declaration ******************/
void usage(char *msg);
unsigned short RGB888toRGB555(unsigned char red,
unsigned char green, unsigned char blue);
void RGB555toRGB888(unsigned char *rgb888,unsigned short *RGB555);
int fb_open(char *fb_device);
int fb_close(int fd);
int fb_stat(int fd, int *width, int *height, int *depth);
void *fb_mmap(int fd, unsigned int screensize);
int fb_munmap(void *start, size_t length);
//int fb_pixel(void *fbmem, int width, int height, int x, int y, unsigned short color);
bool JpegCompress(int w,int h, unsigned char * rgb_data,int rgb_size,unsigned char * jpeg_data,int *jpeg_size);
/************ function implementation ********************/
int
main(int argc, char *argv[])
{
FILE *outfile;
unsigned char *buffer;
/*
* declaration for framebuffer device
*/
int fbdev;
char *fb_device;
unsigned short *fbmem;
unsigned int screensize,RGB555_screensize;
unsigned int fb_width;
unsigned int fb_height;
unsigned int fb_depth;
unsigned int x;
unsigned int y;
int jpeg_size=0;
unsigned char *jpeg_data,*rgb888_data;
/*
* check auguments ??
*/
if (argc != 2) {
usage("insuffient auguments");
exit(-1);
}
/*
* open framebuffer device
*/
if ((fb_device = getenv("FRAMEBUFFER")) == NULL)
fb_device = FB_DEV;
fbdev = fb_open(fb_device);
/*
* get status of framebuffer device
*/
fb_stat(fbdev, &fb_width, &fb_height, &fb_depth);
/*
* map framebuffer device to shared memory
*/
//screensize = fb_width * fb_height * fb_depth / 8;
RGB555_screensize=fb_width * fb_height * fb_depth / 8;
screensize = fb_width * fb_height * 3;
fbmem = (unsigned short *)fb_mmap(fbdev, RGB555_screensize);
rgb888_data=(unsigned char *)malloc(screensize);
jpeg_data=(unsigned char *)malloc(screensize);
RGB555toRGB888(rgb888_data,fbmem);
/*
* open input jpeg file
*/
if ((outfile = fopen(argv[1], "wb")) == NULL) {
fprintf(stderr, "open %s failed\n", argv[1]);
exit(-1);
}
/*
* compress RGB888 to JPEG
*/
if (!JpegCompress(fb_width, fb_height, rgb888_data, screensize, jpeg_data, &jpeg_size))
{
printf("compress error!\n");
}
printf("jpeg size is:%d\n", jpeg_size);
fwrite(jpeg_data, sizeof(jpeg_data), jpeg_size, outfile);
/*
* release memory buffer
*/
free(jpeg_data);
free(rgb888_data);
/*
* close jpeg inputing file
*/
fclose(outfile);
/*
* unmap framebuffer's shared memory
*/
fb_munmap(fbmem, screensize);
/*
* close framebuffer device
*/
fb_close(fbdev);
return (0);
}
void
usage(char *msg)
{
fprintf(stderr, "%s\n", msg);
printf("Usage: fv some-jpeg-file.jpg\n");
}
/* convert 16bit RGB555 to 24bit RGB888 color format
*/
void RGB555toRGB888(unsigned char *rgb888,unsigned short *RGB555)
{
int i,j;
unsigned short *dot;
for (i=0; i<320; i++)
for(j=0;j<240;j++)
{
dot = RGB555+i*240+j;
*rgb888 =(((*dot)&0x
rgb888++;
*rgb888= (((*dot)&0x03E0) >>2); //G
rgb888++;
*rgb888= (((*dot)&0x
rgb888++;
}
}
/*
* open framebuffer device.
* return positive file descriptor if success,
* else return -1.
*/
int
fb_open(char *fb_device)
{
int fd;
if ((fd = open(fb_device, O_RDWR)) < 0) {
perror(__func__);
return (-1);
}
return (fd);
}
/*
* get framebuffer's width,height,and depth.
* return 0 if success, else return -1.
*/
int
fb_stat(int fd, int *width, int *height, int *depth)
{
struct fb_fix_screeninfo fb_finfo;
struct fb_var_screeninfo fb_vinfo;
if (ioctl(fd, FBIOGET_FSCREENINFO, &fb_finfo)) {
perror(__func__);
return (-1);
}
if (ioctl(fd, FBIOGET_VSCREENINFO, &fb_vinfo)) {
perror(__func__);
return (-1);
}
*width = fb_vinfo.xres;
*height = fb_vinfo.yres;
*depth = fb_vinfo.bits_per_pixel;
return (0);
}
/*
* map shared memory to framebuffer device.
* return maped memory if success,
* else return -1, as mmap dose.
*/
void *
fb_mmap(int fd, unsigned int screensize)
{
caddr_t fbmem;
if ((fbmem = mmap(0, screensize, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0)) == MAP_FAILED) {
perror(__func__);
return (void *) (-1);
}
return (fbmem);
}
/*
* unmap map memory for framebuffer device.
*/
int
fb_munmap(void *start, size_t length)
{
return (munmap(start, length));
}
/*
* close framebuffer device
*/
int
fb_close(int fd)
{
return (close(fd));
}
/*
* display a pixel on the framebuffer device.
* fbmem is the starting memory of framebuffer,
* width and height are dimension of framebuffer,
* x and y are the coordinates to display,
* color is the pixel's color value.
* return 0 if success, otherwise return -1.
*/
void JpegInitDestination(j_compress_ptr cinfo)
{}
bool JpegEmptyOutputBuffer(j_compress_ptr cinfo)
{
return TRUE;
}
void JpegTermDestination(j_compress_ptr cinfo)
{}
bool JpegCompress(int w,int h, unsigned char * rgb_data,int rgb_size,unsigned char * jpeg_data,int *jpeg_size)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
struct jpeg_destination_mgr jpegDstManager;
int ret;
//unsigned char *srcBuf = new unsigned char[w * 3];
JSAMPROW rowPointer[1];
//rowPointer[0] = (JSAMPROW)srcBuf;
int left_size,y;
left_size = *jpeg_size;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
cinfo.image_width = w;
cinfo.image_height = h;
cinfo.input_components = 3; // 1,ᅵҶᅵ ᅵᅵᅵλ͌ᅵΪ3
cinfo.in_color_space = JCS_RGB;
cinfo.raw_data_in = TRUE;
jpeg_set_defaults(&cinfo);
cinfo.dest = &jpegDstManager;
jpegDstManager.next_output_byte = (unsigned char*)jpeg_data;
jpegDstManager.free_in_buffer = left_size;
jpegDstManager.init_destination = JpegInitDestination;
jpegDstManager.empty_output_buffer = JpegEmptyOutputBuffer;
jpegDstManager.term_destination = JpegTermDestination;
jpeg_set_quality(&cinfo, 50, TRUE); //ѹᅵᅵ
jpeg_start_compress(&cinfo, TRUE);
for(y=0; y< h; y++)
{
rowPointer[0] = (unsigned char*)(rgb_data + y*w*3);
ret = jpeg_write_scanlines(&cinfo, rowPointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
*jpeg_size = left_size - jpegDstManager.free_in_buffer;
return TRUE;
}