转:利用V4L2获取一张jpeg格式的图片

关于图片压缩和解压缩的内容:http://www.vckbase.com/index.php/wv/1488

1 YUV转RGB

static void YUV422toRGB888(int width, int height, unsigned char *src, unsigned char *dst)
{
 

int line, column;
  unsigned char *py, *pu, *pv;
  unsigned char *tmp = dst;

 
  py = src;
  pu = src + 1;
  pv = src + 3;

  #define CLIP(x) ( (x)>=0xFF ? 0xFF : ( (x) <= 0x00 ? 0x00 : (x) ) )

  for (line = 0; line < height; ++line) {
    for (column = 0; column < width; ++column) {
      *tmp++ = CLIP((double)*py + 1.402*((double)*pv-128.0));
      *tmp++ = CLIP((double)*py - 0.344*((double)*pu-128.0) - 0.714*((double)*pv-128.0));
      *tmp++ = CLIP((double)*py + 1.772*((double)*pu-128.0));

    
      py += 2;
   
      if ((column & 1)==1) {
        pu += 4;
        pv += 4;
      }
    }
  }
}

 

 

 

2 压缩图片

static void process_image(const void * p, int len) {

    //  static char[115200] Outbuff ;



    if (len > 0) {
        unsigned char* src = (unsigned char*)p;
         unsigned char* dst = malloc(width*height*3*sizeof(char));
         YUV422toRGB888(width,height,src,dst);
         write_jpeg("./pic001.jpg",dst,100,width, height, 0);
    }

    fflush(stdout);

}

int write_jpeg(char *filename,unsigned char *buf,int quality,int width, int height, int gray)

{

    struct jpeg_compress_struct cinfo;

    struct jpeg_error_mgr jerr;

    FILE *fp;

    int i;

    unsigned char *line;

    int line_length;



    if (NULL == (fp = fopen(filename,"w")))

    {

                fprintf(stderr,"grab: can't open %s: %s\n",filename,strerror(errno));

                return -1;

    }

    cinfo.err = jpeg_std_error(&jerr);

    jpeg_create_compress(&cinfo);

    jpeg_stdio_dest(&cinfo, fp);

    cinfo.image_width  = width;

    cinfo.image_height = height;

    cinfo.input_components = gray ? 1: 3;

    cinfo.in_color_space = gray ? JCS_GRAYSCALE: JCS_RGB;

    jpeg_set_defaults(&cinfo);

    jpeg_set_quality(&cinfo, quality, TRUE);

    jpeg_start_compress(&cinfo, TRUE);

    line_length = gray ? width : width * 3;

    for (i = 0, line = buf; i < height; i++, line += line_length)

        jpeg_write_scanlines(&cinfo, &line, 1);



    jpeg_finish_compress(&(cinfo));

    jpeg_destroy_compress(&(cinfo));

    fclose(fp);

    return 0;

}

 

 

3 //摄像头采集帧图像的YUYV格式转换为JPEG格式

int compress_yuyv_to_jpeg(unsigned char *buf, unsigned char *buffer, int size, int quality) {

  struct jpeg_compress_struct cinfo;

  struct jpeg_error_mgr jerr;

  JSAMPROW row_pointer[1];

  unsigned char *line_buffer, *yuyv;

  int z;

  static int written;

  //int count = 0;

  //printf("%s\n", buf);

  line_buffer = calloc (WIDTH * 3, 1);

  yuyv = buf;//将YUYV格式的图片数据赋给YUYV指针

  printf("compress start...\n");

  cinfo.err = jpeg_std_error (&jerr);

  jpeg_create_compress (&cinfo);

  /* jpeg_stdio_dest (&cinfo, file); */

  dest_buffer(&cinfo, buffer, size, &written);

  cinfo.image_width = WIDTH;

  cinfo.image_height = HEIGHT;

  cinfo.input_components = 3;

  cinfo.in_color_space = JCS_RGB;

  jpeg_set_defaults (&cinfo);

  jpeg_set_quality (&cinfo, quality, TRUE);

  jpeg_start_compress (&cinfo, TRUE);

  z = 0;

  while (cinfo.next_scanline < HEIGHT) {

    int x;

    unsigned char *ptr = line_buffer;

    for (x = 0; x < WIDTH; x++) {

      int r, g, b;

      int y, u, v;

      if (!z)

        y = yuyv[0] << 8;

      else

        y = yuyv[2] << 8;

      u = yuyv[1] - 128;

      v = yuyv[3] - 128;

      r = (y + (359 * v)) >> 8;

      g = (y - (88 * u) - (183 * v)) >> 8;

      b = (y + (454 * u)) >> 8;

      *(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r);

      *(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g);

      *(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b);

      if (z++) {

        z = 0;

        yuyv += 4;

      }

    } 

    row_pointer[0] = line_buffer;

    jpeg_write_scanlines (&cinfo, row_pointer, 1);

  }

  jpeg_finish_compress (&cinfo);

  jpeg_destroy_compress (&cinfo);

  free (line_buffer);

  return (written);

}

posted @ 2012-11-28 15:24  李伯波  阅读(1009)  评论(0编辑  收藏  举报