图像处理基础(六)-libjpeg常用算法

原创
2018/07/04 16:44
阅读数 1.3K

bmp文件转化为bgr数据

void bmpfile_to_bgr(char *bmp_file,BYTE **rgb,int *size,int *w,int *h,int *bit)
{
    FILE *fp = fopen(bmp_file,"rb");
    if(fp == NULL) return;
    BITMAPFILEHEADER bmpheader;
    BITMAPINFOHEADER bmpinfo;
    fread(&bmpheader,sizeof(BITMAPFILEHEADER),1,fp);
    fread(&bmpinfo,sizeof(BITMAPINFOHEADER),1,fp);
    *rgb = new BYTE[bmpinfo.biSizeImage];
    fread(*rgb,bmpinfo.biSizeImage,1,fp);
    *size = bmpinfo.biSizeImage;
    *w = bmpinfo.biWidth;
    *h = abs(bmpinfo.biHeight);
    *bit = bmpinfo.biBitCount;
    fclose(fp);
}

调用

BYTE *bgr1 = NULL;
int size=0,w=0,h=0,bit=0;
bmpfile_to_bgr("test.bmp",&bgr1,&size,&w,&h,&bit);
free(bgr1);

bgr数据转化为bmp文件

void bgr_to_bmpfile(char *bmp_file,BYTE *rgb,int size,int w,int h,int bit)
{
    FILE *fp = fopen(bmp_file,"wb+");
    if(fp == NULL) return;
 
    BITMAPFILEHEADER bmpheader;
    BITMAPINFOHEADER bmpinfo;
 
    bmpheader.bfType = 0x4d42;
    bmpheader.bfReserved1 = 0;
    bmpheader.bfReserved2 = 0;
    bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bmpheader.bfSize = bmpheader.bfOffBits + size;
 
    bmpinfo.biSize = sizeof(BITMAPINFOHEADER);
    bmpinfo.biWidth = w;
    bmpinfo.biHeight = h;
    bmpinfo.biPlanes = 1;
    bmpinfo.biBitCount = bit;
    bmpinfo.biCompression = BI_RGB;
    bmpinfo.biSizeImage = (w*bit+31)/32*4*h;
    bmpinfo.biXPelsPerMeter = 0;
    bmpinfo.biYPelsPerMeter = 0;
    bmpinfo.biClrUsed = 0;
    bmpinfo.biClrImportant = 0;
         
    fwrite(&bmpheader, sizeof(BITMAPFILEHEADER), 1, fp);
    fwrite(&bmpinfo, sizeof(BITMAPINFOHEADER), 1, fp);
    fwrite(rgb, size, 1, fp);
 
    fclose(fp);
}

调用

bgr_to_bmpfile("test.bmp",bgr1,size,w,h,bit);

翻转r-b分量

bmp的分量是以bgr保存的,但是libjpeg使用的是rgb,所以需要翻转br分量

void bgr_flip_rgb(BYTE *bgr,int size,int bit)
{
    int i = 0;
    for(;i<size;i+=bit/8){
        BYTE b = bgr[i];
        bgr[i] = bgr[i+2];
        bgr[i+2] = b;
    }
}

jpg文件转jpg内存数据

void jpgfile_to_jpgmem(char *jpg_file,BYTE **jpg,int *size)
{
    FILE *fp = fopen(jpg_file,"rb");
    if(fp == NULL) return;
     
    fseek(fp,0,SEEK_END);
    int length = ftell(fp);
    fseek(fp,0,SEEK_SET);
     
    *jpg = new BYTE[length];
    fread(*jpg,length,1,fp);
    *size = length;
     
    fclose(fp);
}

调用

BYTE *jpg = NULL;
int size = 0;
jpgfile_to_jpgmem("Tulips.jpg",&jpg,&size);
free(jpg);

jpg内存数据转jpg文件

void jpgmem_to_jpgfile(char *jpg_file,BYTE *jpg,int size)
{
    FILE *fp = fopen(jpg_file,"wb+");
    if(fp == NULL) return;
    fwrite(jpg,size,1,fp);
    fclose(fp);
}

bgr数据转jpg内存数据

void bgr_to_jpgmem(BYTE *rgb,int size,int w,int h,int bit,BYTE **jpg,int *j_size)
{
    struct jpeg_error_mgr jerr;
    jpeg_std_error(&jerr);
     
    struct jpeg_compress_struct cinfo;
    cinfo.err = &jerr;
    jpeg_create_compress(&cinfo);
     
    jpeg_mem_dest(&cinfo,jpg,(unsigned long*)j_size);
     
    cinfo.image_width = w;
    cinfo.image_height = h;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;
     
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, 100, TRUE);
    jpeg_start_compress(&cinfo,TRUE);
    int row_stride = cinfo.image_width*cinfo.input_components;
     
    JSAMPROW row_pointer[1];
    while(cinfo.next_scanline < cinfo.image_height)
    {
        row_pointer[0] = & rgb[(cinfo.image_height-cinfo.next_scanline-1)*row_stride];
        (void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
}

bgr数据转为jpg文件

void bgr_to_jpgfile(BYTE *rgb,int size,int w,int h,int bit,char *jpgfile)
{
    struct jpeg_error_mgr jerr;
    jpeg_std_error(&jerr);
     
    struct jpeg_compress_struct cinfo;
    cinfo.err = &jerr;
    jpeg_create_compress(&cinfo);
     
    FILE *fp = fopen(jpgfile,"wb+");
    jpeg_stdio_dest(&cinfo,fp);
    //jpeg_mem_dest(&cinfo,jpg,(unsigned long*)j_size);
     
    cinfo.image_width = w;
    cinfo.image_height = h;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;
     
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, 100, TRUE);
    jpeg_start_compress(&cinfo,TRUE);
    int row_stride = cinfo.image_width*cinfo.input_components;
     
    JSAMPROW row_pointer[1];
    while(cinfo.next_scanline < cinfo.image_height)
    {
        //row_pointer[0] = & rgb[cinfo.next_scanline * row_stride];
        row_pointer[0] = & rgb[(cinfo.image_height-cinfo.next_scanline-1)*row_stride];
        (void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }
    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
     
    fclose(fp);
}

jpg内存数据->bgr数据

void jpgmem_to_bgr(BYTE *jpg,int size,BYTE **bgr,int *b_size,int *w,int *h)
{
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;
    cinfo.err = jpeg_std_error(&jerr);
     
    jpeg_create_decompress(&cinfo);
    jpeg_mem_src(&cinfo,jpg,size);
     
    jpeg_read_header(&cinfo,TRUE);
    jpeg_start_decompress(&cinfo);
     
    unsigned long width = cinfo.output_width;
    unsigned long height = cinfo.output_height;
    unsigned short depth = cinfo.output_components;
     
    *w = width;
    *h = height;
    *b_size = width*height*depth;
    *bgr = (BYTE*)malloc(width*height*depth);
    memset(*bgr,0,width*height*depth);
     
    JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, width*depth,1);
     
    BYTE *point = (*bgr)+(height-cinfo.output_scanline-1)*(width*depth);
    while(cinfo.output_scanline<height)
    {
        jpeg_read_scanlines(&cinfo, buffer, 1);
        memcpy(point, *buffer, width*depth);
        point -= width*depth;
    }
     
    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
}

调用

BYTE *jpg = NULL;
int j_size = 0;
jpgfile_to_jpgmem("Tulips.jpg",&jpg,&j_size);
 
BYTE *bgr = NULL;
int size,w,h,bit=24;
jpgmem_to_bgr(jpg,j_size,&bgr,&size,&w,&h);
bgr_flip_rgb(bgr,size,bit);
bgr_to_bmpfile("Tulips2.bmp",bgr,size,w,h,bit);
free(bgr);
 
free(jpg);
展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部