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; }