使用libjpeg库在图片上画方框

#include <stdio.h>
#include <stdlib.h>
#include <jpeglib.h>
#include <memory.h>

int camera_W = 640;
int camera_H = 640;
int read_JPEG_file (char * filename, unsigned char *out_buf,int size)
{
      struct jpeg_decompress_struct           cinfo;
      struct jpeg_error_mgr                   jerr;
      /*  More stuff */
      FILE                                    *infile;                /*  source file */
      int                                     row_stride;               /*  physical row width in output buffer */
      unsigned char                           *rdata;
      JSAMPROW                                row_pointer[1];
      int                                     image_size = 0 ;

      if ((infile = fopen(filename, "rb")) == NULL)
      {
      fprintf(stderr, "can't open %s\n", filename);
      return -1;
      }

      /*  Step 1: allocate and initialize JPEG decompression object */

      /*  We set up the normal JPEG error routines, then override error_exit. */
      cinfo.err = jpeg_std_error(&jerr);
      /*  Now we can initialize the JPEG decompression object. */
      jpeg_create_decompress(&cinfo);
      /*  Step 2: specify data source (eg, a file) */
      jpeg_stdio_src(&cinfo, infile);

      /*  Step 3: read file parameters with jpeg_read_header() */
      (void) jpeg_read_header(&cinfo, TRUE);

      /*  源信息 */

      printf("image_width = %d\n", cinfo.image_width);
      printf("image_height = %d\n", cinfo.image_height);
      printf("num_components = %d\n", cinfo.num_components);
      image_size = cinfo.image_width*cinfo.image_height*cinfo.num_components ;

      //传进来的字符数组没有足够大的空间
      if(size < image_size )
      {
            printf("buf size too small!\n") ;
            return -2 ;
      }
      /*   分配内存存储字节   */
      rdata=(unsigned char*)calloc(image_size,1);
      /*  Step 4: set parameters for decompression */
      //设置输出的颜色类型

      cinfo.out_color_space=JCS_RGB;
      /*  Step 5: Start decompressor */
      (void) jpeg_start_decompress(&cinfo);

      /*  输出的图象的信息 */

      printf("output_width = %d\n", cinfo.output_width);
      printf("output_height = %d\n", cinfo.output_height);
      printf("output_components = %d\n", cinfo.output_components);//解压的是rgb,故为3元素
      /*  JSAMPLEs per row in output buffer */

      row_stride = cinfo.output_width * cinfo.output_components;//一行的数据长度

      /*  Make a one-row-high sample array that will go away when done with image */
      /*  Step 6: while (scan lines remain to be read) */
      /*            jpeg_read_scanlines(...); */
      while (cinfo.output_scanline < cinfo.output_height)
      {
            row_pointer[0] = & rdata[(cinfo.output_scanline)*cinfo.image_width*cinfo.num_components];
            jpeg_read_scanlines(&cinfo,row_pointer ,1);
            //(void) jpeg_read_scanlines(&cinfo, buffer, 1);
            /*  Assume put_scanline_someplace wants a pointer and sample count. */
            //put_scanline_someplace(buffer[0], row_stride);
      }
      memcpy(out_buf, rdata, image_size) ;
      free(rdata) ;
      (void) jpeg_finish_decompress(&cinfo);
      /*  Step 8: Release JPEG decompression object */
      /*  This is an important step since it will release a good deal of memory. */
      jpeg_destroy_decompress(&cinfo);

      fclose(infile);
      /*  And we're done! */
      return image_size;
}
 
int write_JPEG_file (char * filename,unsigned char *image_buffer, int image_width, int image_height, int quality )
{
      struct jpeg_compress_struct cinfo;
      struct jpeg_error_mgr jerr;

      /*  More stuff */
      FILE * outfile;               /*  target file */
      JSAMPROW row_pointer[1];      /*  pointer to JSAMPLE row[s] */
      int row_stride;               /*  physical row width in image buffer */
      /*  Step 1: allocate and initialize JPEG compression object */
      cinfo.err = jpeg_std_error(&jerr);
      /*  Now we can initialize the JPEG compression object. */
      jpeg_create_compress(&cinfo);
      /*  Step 2: specify data destination (eg, a file) */

      /*  Note: steps 2 and 3 can be done in either order. */

      if ((outfile = fopen(filename, "w+")) == NULL) {
            fprintf(stderr, "can't open %s\n", filename);
            return -1;
      }
      jpeg_stdio_dest(&cinfo, outfile);

      /*  Step 3: set parameters for compression */
      cinfo.image_width = image_width;      /*  image width and height, in pixels */
      cinfo.image_height = image_height;
      cinfo.input_components = 3;           /*  # of color components per pixel */
      cinfo.in_color_space = JCS_RGB;       /*  colorspace of input image */

      jpeg_set_defaults(&cinfo);
      jpeg_set_quality(&cinfo, quality, TRUE /*  limit to baseline-JPEG values */);

      /*  Step 4: Start compressor */
      jpeg_start_compress(&cinfo, TRUE);

      /*  Step 5: while (scan lines remain to be written) */
      row_stride = image_width * 3; /*  JSAMPLEs per row in image_buffer */

      while (cinfo.next_scanline < cinfo.image_height) 
      {
            row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
            (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
      }

      /*  Step 6: Finish compression */
      jpeg_finish_compress(&cinfo);

      /*  After finish_compress, we can close the output file. */
      fclose(outfile);

      /*  Step 7: release JPEG compression object */
      /*  This is an important step since it will release a good deal of memory. */
      jpeg_destroy_compress(&cinfo);
      /*  And we're done! */
      return 0 ;
}
typedef struct _jpg_color_ 
{
      unsigned char R;
      unsigned char G;
      unsigned char B;
}COLOR;

void Draw_square(COLOR *p , int start_x , int end_x , int start_y , int end_y , COLOR color={0, 255, 0}, int width = 5)
{
      int x1,x2,y1,y2;
      int x,y;

      if(start_x==end_x || start_y==end_y)
            return;//如果不符合就直接返回
      /* start_x与end_x哪个大哪个赋值x2,小的赋值x1 */

      if(start_x<end_x)
      {
            x1=start_x;
            x2=end_x;
      }
      else
      {
            x2=start_x;
            x1=end_x;
      }

      /* start_y与end_y哪个大哪个赋值y2,小的赋值y1 */
      if(start_y<end_y)
      {
            y1=start_y;
            y2=end_y;
      }
      else
      {
            y2=start_y;
            y1=end_y;
      }

      //超出边界就取边界值
      if(x1<0)x1=0; 
      if(x2>(camera_W-1))
            x2=camera_W-1;

      if(y1<0)
            y1=0;

      if(y2>(camera_H-1))
            y2=camera_H-1;

      //遍历通道
      for(x=x1; x<x2; x++)
      {      
            for (int i = 0; i < width; i++)
            {
                  //p[(start_y * 3 + i)*camera_W+x]=color.value;
                  memcpy(&p[(start_y + i)*camera_W+x], &color, sizeof(COLOR));
                  memcpy(&p[(end_y - i)*camera_W+x], &color, sizeof(COLOR));
            }
      }
      
      for(y=y1; y<y2; y++)
      {
            for (int i = 0; i < width; i++)
            {
                  memcpy(&p[y*camera_W+(start_x + i)], &color, sizeof(COLOR));
                  memcpy(&p[y*camera_W+(end_x - i)], &color, sizeof(COLOR));
            }
      }
}

int main(int argc, char **argv)
{
      int                     rv =  -1 ;
      int                     result =  0 ;
      unsigned char           buffer[640*640*3] ;
      unsigned short          rgb565_buf[640*640] ;
      unsigned char           rgb888_buf[640*640*3] ;

      memset(buffer,0, sizeof(buffer)) ;

      rv = read_JPEG_file((char*)"/data/ObjDetector/objectdetector/resource/640-640.jpg",buffer,sizeof(buffer)) ;//读取OV2640采集到的JPEG图像解码为RGB888数据
      if(rv < 0)
      {
            printf("read_JPEG_file() failed\n") ;
            return -1 ;
      }

      printf("jpeg decompress OK, after decompress size = %d\n",rv) ;
      Draw_square((COLOR*)buffer , 100 , 200 , 100 , 200);

      write_JPEG_file((char*)"new_test.jpg",buffer,640,640,75) ;//RGB888编码保存jpg图片文件

      printf("rgb write jpeg compress finish!\n") ;

      return 0 ;



}/* End Of Main */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值