1. 程式人生 > >實現影象格式的轉換程式碼 C語言實現 RGB565轉BMP影象

實現影象格式的轉換程式碼 C語言實現 RGB565轉BMP影象

這是我從網上看到的寶貴資料,可以直接實現RGB565 轉BMP影象的實現。我是用的開發板mini2440的開發板,和配套的攝像頭CAM130,實際上CAM130用的是OV9650的一款攝像頭;拍出的照片為RGB565的格式,因為這種格式直接可以送到 TFT螢幕上直接顯示;

轉自:

http://www.360doc.com/content/14/0324/11/16450474_363247832.shtml#

非常好的資料,真實可用;

//主函式
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "rgb2bmp.h"
int  main()
{    FILE* p;
/***************  input data  ***********
filename      :RGB資料檔名稱
nWidth        :所生成檔案的水平畫素
nHeight       :所生成檔案的垂直畫素
newFile       :最終生成檔案的名稱
***********************************************/
char* filename = "rgb565_800_480_woman";
int nWidth = 800;
int nHeight = 480;
char* newFile = "rgb565_800_480_woman_0x7f.bmp";
p = fopen(filename,"rb");
if (p == NULL)
{
printf("!!!file %s open failed.n", filename);
return 0;
}
printf("file %s open success.n",filename);
/***********  read Image Data  **************/    
long nData = nWidth*nHeight;
unsigned short
* rgb_buffer = malloc(nData*sizeof(short));   
fread(rgb_buffer,2,nData,p);
long total = nWidth*nHeight*3;
unsigned char* pVisit =  malloc(total*sizeof(char));
unsigned char* tmp = pVisit;
long i =0;
unsigned char R,G,B;
while(i<nData)
{
R = *rgb_buffer&0x1f;
G = (*rgb_buffer>>5)&0x3f;
B = (*rgb_buffer>>11)&0x1f;
B = B<<3;
G = G<<2;
R = R<<3;
*pVisit=R;pVisit++;
*pVisit=G;pVisit++;
*pVisit=B;pVisit++;
rgb_buffer++;
i++; 
}
printf("read file over.nData%ldn",nData);
/*****************************************************/
/***********  write file *******************/
FILE *result = fopen(newFile,"wb");
if (result == NULL)
{
printf("open new file failed.n");
return -1;
}
RGB2BMP(tmp,nWidth,nHeight,result);
fclose(result);
return 0;
}
//rgb2bmp.h檔案
#include <stdio.h>
typedef unsigned char  BYTE;
typedef unsigned short WORD;
// BMP影象各部分說明如下
/***********
第一部分    點陣圖檔案頭
該結構的長度是固定的,為14個位元組,各個域的依次如下:
2byte   :檔案型別,必須是0x4d42,即字串"BM"。
4byte   :整個檔案大小
4byte   :保留字,為0
4byte   :從檔案頭到實際的點陣圖影象資料的偏移位元組數。
*************/
typedef struct
{    long imageSize;
long blank;
long startPosition;
}BmpHead;
/*********************
/*********************
第二部分    點陣圖資訊頭
該結構的長度也是固定的,為40個位元組,各個域的依次說明如下:
4byte   :本結構的長度,值為40
4byte   :影象的寬度是多少象素。
4byte   :影象的高度是多少象素。
2Byte   :必須是1。
2Byte   :表示顏色時用到的位數,常用的值為1(黑白二色圖)、4(16色圖)、8(256色圖)、24(真彩色圖)。
4byte   :指定點陣圖是否壓縮,有效值為BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS。Windows點陣圖可採用RLE4和RLE8的壓縮格式,BI_RGB表示不壓縮。
4byte   :指定實際的點陣圖影象資料佔用的位元組數,可用以下的公式計算出來:
影象資料 = Width' * Height * 表示每個象素顏色佔用的byte數(即顏色位數/8,24bit圖為3,256色為1)
要注意的是:上述公式中的biWidth'必須是4的整數倍(不是biWidth,而是大於或等於biWidth的最小4的整數倍)。
如果biCompression為BI_RGB,則該項可能為0。
4byte   :目標裝置的水平解析度。
4byte   :目標裝置的垂直解析度。
4byte   :本影象實際用到的顏色數,如果該值為0,則用到的顏色數為2的(顏色位數)次冪,如顏色位數為8,2^8=256,即256色的點陣圖
4byte   :指定本影象中重要的顏色數,如果該值為0,則認為所有的顏色都是重要的。
***********************************/
typedef struct
{
long    Length;
long    width;
long    height;
WORD    colorPlane;
WORD    bitColor;
long    zipFormat;
long    realSize;
long    xPels;
long    yPels;
long    colorUse;
long    colorImportant;
/*  void show()
{    
printf("infoHead Length:%dn",Length);
printf("width&height:%d*%dn",width,height);
printf("colorPlane:%dn",colorPlane);
printf("bitColor:%dn",bitColor);
printf("Compression Format:%dn",zipFormat);
printf("Image Real Size:%dn",realSize);
printf("Pels(X,Y):(%d,%d)n",xPels,yPels);
printf("colorUse:%dn",colorUse);    
printf("Important Color:%dn",colorImportant);
}*/
}InfoHead;
/***************************
/***************************
第三部分    調色盤結構  顏色表
對於256色BMP點陣圖,顏色位數為8,需要2^8 = 256個調色盤;
對於24bitBMP點陣圖,各象素RGB值直接儲存在影象資料區,不需要調色盤,不存在調色盤區
rgbBlue:   該顏色的藍色分量。
rgbGreen:  該顏色的綠色分量。
rgbRed:    該顏色的紅色分量。
rgbReserved:保留值。
************************/
typedef struct
{         BYTE   rgbBlue;
BYTE   rgbGreen;
BYTE   rgbRed;
BYTE   rgbReserved;
/*   void show(void)
{
printf("Mix Plate B,G,R:%d %d %dn",rgbBlue,rgbGreen,rgbRed);
}*/
}RGBMixPlate;
/****************************
RGB加上頭部資訊轉換成BMP
引數說明:
rgb_buffer        :RGB資料檔案中的資訊
nData             :RGB資料的長度
nWidth            :影象寬度的畫素數
nHeight           :影象高度的畫素數
fp1               :所存放的檔案
*****************************/
int RGB2BMP(char *rgb_buffer,int nWidth,int nHeight,FILE*fp1)
{
BmpHead m_BMPHeader;       
char bfType[2]={'B','M'};
m_BMPHeader.imageSize=3*nWidth*nHeight+54;
m_BMPHeader.blank=0;
m_BMPHeader.startPosition=54;
fwrite(bfType,1,sizeof(bfType),fp1);
fwrite(&m_BMPHeader.imageSize,1,sizeof(m_BMPHeader.imageSize),fp1);
fwrite(&m_BMPHeader.blank,1,sizeof(m_BMPHeader.blank),fp1);
fwrite(&m_BMPHeader.startPosition,1,sizeof(m_BMPHeader.startPosition),fp1);
InfoHead  m_BMPInfoHeader;
m_BMPInfoHeader.Length=40;
m_BMPInfoHeader.width=nWidth;
m_BMPInfoHeader.height=nHeight;
m_BMPInfoHeader.colorPlane=1;
m_BMPInfoHeader.bitColor=24;
m_BMPInfoHeader.zipFormat=0;
m_BMPInfoHeader.realSize=3*nWidth*nHeight;
m_BMPInfoHeader.xPels=0;
m_BMPInfoHeader.yPels=0;
m_BMPInfoHeader.colorUse=0;
m_BMPInfoHeader.colorImportant=0;
fwrite(&m_BMPInfoHeader.Length,1,sizeof(m_BMPInfoHeader.Length),fp1);
fwrite(&m_BMPInfoHeader.width,1,sizeof(m_BMPInfoHeader.width),fp1);
fwrite(&m_BMPInfoHeader.height,1,sizeof(m_BMPInfoHeader.height),fp1);
fwrite(&m_BMPInfoHeader.colorPlane,1,sizeof(m_BMPInfoHeader.colorPlane),fp1);
fwrite(&m_BMPInfoHeader.bitColor,1,sizeof(m_BMPInfoHeader.bitColor),fp1);
fwrite(&m_BMPInfoHeader.zipFormat,1,sizeof(m_BMPInfoHeader.zipFormat),fp1);
fwrite(&m_BMPInfoHeader.realSize,1,sizeof(m_BMPInfoHeader.realSize),fp1);
fwrite(&m_BMPInfoHeader.xPels,1,sizeof(m_BMPInfoHeader.xPels),fp1);
fwrite(&m_BMPInfoHeader.yPels,1,sizeof(m_BMPInfoHeader.yPels),fp1);
fwrite(&m_BMPInfoHeader.colorUse,1,sizeof(m_BMPInfoHeader.colorUse),fp1);
fwrite(&m_BMPInfoHeader.colorImportant,1,sizeof(m_BMPInfoHeader.colorImportant),fp1);
fwrite(rgb_buffer,3*nWidth*nHeight,1,fp1);
return 0;
}