您的位置:首页 > 其它

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

2013-02-24 17:32 555 查看
  RGB1555->RGB888

  1#  生成RGB24图片水平位移

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

      解决: 

/* 跳过bmp文件头,直接读取掌纹图像数据 */
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: lvzaina@gmail.com
> 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: lvzaina@gmail.com
> 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: