BMP图片转JPG小记(使用libjpeg,RGB1555->RGB888)

  RGB1555->RGB888

  1#  生成RGB24图片水平位移

        原因:  将bmp文件信息头一并读入

      解决:  

1    /* 跳过bmp文件头,直接读取掌纹图像数据 */

2    fseek(fd, 54, SEEK_SET);  

 

  2#  生成RGB888图片颜色不对,本人遇到情况为图片有很多绿色波纹,只能看到图像轮廓。

        原因: 原始图片为RGB1555格式,我误认为是为RGB565格式。

      解决: 调整转码代码。

    /* 详见文章尾所附代码 */

  3#  生成图片部分色彩正确部分错误,本人遇到情况为带图片波纹,许多地方红颜色覆盖

      原因:  转码代码中,有位移方向错误

      解决: 调整转码代码。

    /* 错误代码 */

    static void pixel_rgb555_to_rgb24(const unsigned char *p16,unsigned char *p24) 

    {  

        *(p24+0)=(*(unsigned short*)p16 << 3) & 0xF8; /* B */

        *(p24+1)=(*(unsigned short*)p16 >> 2) & 0xF8; /* G */

        *(p24+2)=(*(unsigned short*)p16 << 7) & 0xF8; /* R */

    } 

    /* 正确代码 */

    static void pixel_rgb555_to_rgb24(const unsigned char *p16,unsigned char *p24) 

    {  

        *(p24+0)=(*(unsigned short*)p16 << 3) & 0xF8; /* B */

        *(p24+1)=(*(unsigned short*)p16 >> 2) & 0xF8; /* G */

        *(p24+2)=(*(unsigned short*)p16 >> 7) & 0xF8; /* R */

    } 

  RGB888->JPEG (使用libjpeg)

  1#  运行报错,生成图片失败

      错误:  

     [root@vm jj]# ./bmp2jpg
     Bogus input colorspace

        原因:  cinfo.in_color_spaces 与 cinfo.input_components 设置错误,

      解决:  components 为 1 对应 in_color_spaces 为 JCS_GRAYSCALE 生成灰度图,components 为 3 对应 in_color_spaces 为 JCS_RGB生成彩色图

    cinfo.input_components = 3;         /* # of color components per pixel */
   cinfo.in_color_space = JCS_RGB; //JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像

 

 RGB1555->RGB888

/*************************************************************************

    > File Name: RGB555ToRGB888.cpp

    > Function: convert rgb555 to rgb888 

    > update: lvc

    > Mail: [email protected] 

    > Created Time: 2013年02月24日 星期日 02时55分22秒

    > Quote From: http://blog.csdn.net/yinuodie/article/details/8194804

************************************************************************/



#include <stdio.h>  

#include <string.h>  

#include "bmp.h"  

  

  

#define WIDTH       (320)  

#define HEIGHT      (240)  

#define IMAGESIZE16 ((WIDTH)*(HEIGHT)*2)  

#define IMAGESIZE24 ((IMAGESIZE16/2)*3)  

  

#define _DEBUG_ printf("-----------\n");  

  

void pixel_rgb555_to_rgb24(const unsigned char *p16,unsigned char *p24) //将16bit的像素转化为24bit的像素  

{  

    unsigned char R,G,B;  

    B=(*(unsigned short*)p16 << 3) & 0xF8; 

    G=(*(unsigned short*)p16 >> 2) & 0xF8;  

    R=(*(unsigned short*)p16 >> 7) & 0xF8;  

    *(p24+0)=B;   

    *(p24+1)=G;  

    *(p24+2)=R;  

}   

void pixel_rgb565_to_rgb24(const unsigned char *p16,unsigned char *p24) //将16bit的像素转化为24bit的像素  

{  

    unsigned char R,G,B;  

    B=*(unsigned short*)p16 & 0x01F;  

    G=(*(unsigned short*)p16 & 0x7E0) >> 5;  

    R=(*(unsigned short*)p16 >> 11 ) & 0x1F;  

    *(p24+0)=B << 2;   

    *(p24+1)=G << 1;  

    *(p24+2)=R << 2;  

}   

void image16_to_image24(const unsigned char *image16, unsigned char *image24, int biWidth, int biHeight)  

{  

    const unsigned char *p16 = image16;  

    unsigned char *p24 = image24;  

    int i;  

    for(i=0; i<biWidth*biHeight; i++, p16+=2, p24+=3)  

    {  

        pixel_rgb555_to_rgb24(p16, p24);  

    }  

}  

  

int main()  

{  

    //BITMAPFILEHEADER bmp_fileheader;  

    unsigned char bmp_fileheader[14];   //位图文件头  

    BITMAPINFOHEADER bmp_infoheader;    //位图信息头  

  

    //位图文件头  

        //因为字节对齐的问题,所以位图文件头用数组来定义   

    *(WORD *)bmp_fileheader = 'B' | 'M' << 8; //bfType 文件标识'BM'  

    *(DWORD *)(bmp_fileheader + 2) = 14 + 40 + IMAGESIZE24;     //bfSize 文件的大小  

    *(DWORD *)(bmp_fileheader + 6) = 0; //bfReserved1 和 bfReserved2  

    *(DWORD *)(bmp_fileheader + 10) = 54;   //bfOffBits 图象数据RGBA的起始地址的偏移值  为54   

  

    //位图信息头  

    bmp_infoheader.biSize = 40;  

    bmp_infoheader.biWidth = WIDTH;                     //图像width  

    bmp_infoheader.biHeight = HEIGHT;                       //图像height  

    bmp_infoheader.biPlanes = 1;  

    bmp_infoheader.biBitCount = 24;                     //像素精度  

    bmp_infoheader.biCompression = 0;  

    bmp_infoheader.biSizeImage = IMAGESIZE24;               //图像大小  

    bmp_infoheader.biXPelsPerMeter = 0;  

    bmp_infoheader.biYPelsPerMeter = 0;  

    bmp_infoheader.biClrUsed = 0;  

    bmp_infoheader.biClrImportant = 0;  

  

    unsigned char *imagedata16 = new unsigned char[IMAGESIZE16];  

    unsigned char *imagedata24 = new unsigned char[IMAGESIZE24];  

  

    FILE *image = fopen("b.bmp", "rb");  

    fseek(image, 54, SEEK_SET);  

        fread(imagedata16, IMAGESIZE16, 1, image);  

    fclose(image);  

  

      

    image16_to_image24(imagedata16, imagedata24, 320, 240);  

  

    FILE *file = fopen("bmp24.bmp", "wb");  

        fwrite(bmp_fileheader, 14, 1, file);  

        fwrite(&bmp_infoheader, 40, 1, file);  

        fwrite(imagedata24, IMAGESIZE24, 1, file);  

    fclose(file);  

    delete []imagedata16;  

    delete []imagedata24;  

  return 0;

}  

RGB888->JPEG

/*************************************************************************

    > File Name: rgb555tojpg.c

    > Function: convert rgb555 to rgb888 to jpg

    > Author: lvc

    > Mail: [email protected] 

    > Created Time: 2013年02月24日 星期日 02时55分22秒

 ************************************************************************/



#include <string.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <sys/ioctl.h>

#include <sys/mman.h>

#include <linux/videodev.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

#include <errno.h>

#include <stdlib.h>

#include <signal.h>

#include <sys/timeb.h>

#include <jpeglib.h>



#define JPEG_QUALITY 90



static void pixel_rgb555_to_rgb24(const unsigned char *p16,unsigned char *p24) //将16bit的像素转化为24bit的像素  

{  

    *(p24+0)=(*(unsigned short*)p16 << 3) & 0xF8; /* B */

    *(p24+1)=(*(unsigned short*)p16 >> 2) & 0xF8; /* G */

    *(p24+2)=(*(unsigned short*)p16 >> 7) & 0xF8; /* R */

} 

static void image16_to_image24(const unsigned char *image16, unsigned char *image24, int biWidth, int biHeight)  

{  

    const unsigned char *p16 = image16;  

    unsigned char *p24 = image24;  

    int i;  

    for(i=0; i<biWidth*biHeight; i++, p16+=2, p24+=3)  

    {  

        pixel_rgb555_to_rgb24(p16, p24);  

    }  

} 

int main()

{

  FILE *fd;

  int ret;

  int i,j=0;

  long rgb_index = 0;

  unsigned char *imageRGB16;

  unsigned char *imageRGB24;

  int sizeImageRGB16 = 320*240*2;

  int sizeImageRGB24 = 320*240*3;

  imageRGB16 = (unsigned char*)malloc(sizeImageRGB16);

  imageRGB24 = (unsigned char*)malloc(sizeImageRGB24);

  fd = fopen("b.bmp", "rb");

  if(!fd)

  {

    printf("ERROR1: Can not open the image.\n");

    free(imageRGB16);

    free(imageRGB24);

    return -1;

  }



  /* 跳过bmp文件头,直接读取掌纹图像数据 */

  fseek(fd, 54, SEEK_SET);  

  ret = fread(imageRGB16, sizeImageRGB16, 1, fd);

  if(ret == 0)

  {

    if(ferror(fd))

    {

      printf("\nERROR2: Can not read the pixel data.\n");

      free(imageRGB16);

      free(imageRGB24);

      fclose(fd);

      return -1;

    }

  }

  fclose(fd);

  image16_to_image24(imageRGB16,imageRGB24,320,240);

  char *filename = "jpg.jpg";

  int width = 320;

  int height = 240;

  int depth = 3;

  //unsigned char *bits = "jsdgjksdjkgjks51sd536gsgjmskjgksjgss231h1b2s123z";

  struct jpeg_compress_struct cinfo;

  struct jpeg_error_mgr jerr;

  FILE *outfile;                 /* target file */

  JSAMPROW *row_pointer;        /* pointer to JSAMPLE row[s] */

  int     row_stride;             /* physical row width in image buffer */



  cinfo.err = jpeg_std_error(&jerr);

  /* Now we can initialize the JPEG compression object. */

  jpeg_create_compress(&cinfo);



  if ((outfile = fopen(filename, "wb")) == NULL) {

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

    return -1;

  }

  jpeg_stdio_dest(&cinfo, outfile);



  cinfo.image_width = width;      /* image width and height, in pixels */

  cinfo.image_height = height;

  cinfo.input_components = depth;         /* # of color components per pixel */

  cinfo.in_color_space = JCS_RGB;         /* colorspace of input image */



  jpeg_set_defaults(&cinfo);

  /* Now you can set any non-default parameters you wish to.

  * Here we just illustrate the use of quality (quantization table) scaling:

  */

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



  jpeg_start_compress(&cinfo, TRUE);



  row_pointer = malloc(height*width*3);

  char * line[height];



  for(i=0;i<height;i++)

  {    

    unsigned char * lineData = NULL;

    

    lineData = malloc(width*3);

    line[i]  = lineData;

    

    for(j=0;j<width;j++)

    {

      lineData[j*3+2] = imageRGB24[rgb_index];

      rgb_index ++;

      lineData[j*3+1] = imageRGB24[rgb_index];

      rgb_index ++;

      lineData[j*3+0] = imageRGB24[rgb_index];

      rgb_index ++;

    }

    

    row_pointer[height-i-1] = lineData;      

  }

  

  jpeg_write_scanlines(&cinfo, row_pointer, height);

  jpeg_finish_compress(&cinfo);

  jpeg_destroy_compress(&cinfo);



  for (i=0; i<height; i++)

  {

    free(line[i]);

  }

  free(row_pointer);

  free(imageRGB16);

  free(imageRGB24);

  fclose(outfile);



  return 0;

}

 

 

 

 

 

你可能感兴趣的:(lib)