// readBmp.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bmp.h"
//////////////////////////////////////////////////////////////////////
//全局变量区
/////////////////////////
BYTE * G_cpPicRGB_Data; // 全局变量,加载和保存时存放的图像数据
int G_nPicWidth = 0; // 全局变量,picture width
int G_nPicHeight = 0; // 全局变量,picture height
//////////////////////////////////////////////////////////////////////////
//函数声明区
//////////////////////////
/*加载24位的BMP位图,读取出的RGB图像数据按顺序存放在全局变量G_cpPicRGB_Data中*/
void LoadBmp ( char *cName );
/*把全局变量G_cpPicRGB_Data中的RGB数据写入文件并保存*/
void SaveBmp ( char *cName );
/*从全局变量G_cpPicRGB_Data中获取RGB三个分量存放在PicData类型的结构体pPic_RGBStruct_Data_out(输出参数)中*/
void Get_Pic_RGBStruct_Data(PicData * pPic_RGBStruct_Data_out);
/*从PicData类型的结构体pPic_RGBStruct_Data_in(输入参数)中获取RGB数据存放到G_cpPicRGB_Data*/
void Set_Pic_Data(PicData * pPic_RGBStruct_Data_in);
/*输入参数pPic_RGBStruct_Data_in中PicData类型的数据对应的RGB分量转化为YUV*/
void RGB2YUV(double* imageY, double* imageU, double* imageV, PicData* pPic_RGBStruct_Data_in);
/*YUV转化为RBG保存在输出参数pPic_RGBStruct_Data_out中*/
void YUV2RGB(PicData* pPic_RGBStruct_Data_out, double* imageY, double* imageU, double* imageV);
/*处理dbData,使其在min和max之间,如果小于min,则等于min;同样,如果大于max,则等于max*/
double Clamp(double dbData,int min,int max);
int main()
{
double *image_Y;
double *image_U;
double *image_V;
char* cFullName_in = "image_in/pic0001.bmp";
char* cFullName_out = "image_out/pic0001_out.bmp";
PicData * pPic_RGBStruct_Data;
LoadBmp (cFullName_in);
pPic_RGBStruct_Data = (PicData*)(malloc(G_nPicHeight * G_nPicWidth * sizeof(PicData)));
Get_Pic_RGBStruct_Data(pPic_RGBStruct_Data);
image_Y = (double*)(malloc(G_nPicHeight * G_nPicWidth * sizeof(double)));
image_U = (double*)(malloc(G_nPicHeight * G_nPicWidth * sizeof(double)));
image_V = (double*)(malloc(G_nPicHeight * G_nPicWidth * sizeof(double)));
RGB2YUV(image_Y,image_U,image_V,pPic_RGBStruct_Data);
YUV2RGB(pPic_RGBStruct_Data,image_Y,image_U,image_V);
Set_Pic_Data(pPic_RGBStruct_Data);
SaveBmp ( cFullName_out );
free(pPic_RGBStruct_Data);
free(image_Y);
free(image_U);
free(image_V);
return 0;
}
//////////////////////////////////////////////////////////////////////////
//函数定义区
//////////////////////////
/*加载24位的BMP位图,读取出的RGB图像数据按顺序存放在全局变量G_cpPicRGB_Data中*/
void LoadBmp( char *cName )
{
FILE *fp = 0;
int ni = 0 ;
int nj = 0 ; // no user
int LineBytes ;
unsigned char PadZeros[4] ;
if ( cName == NULL )
{
printf( "[LoadBmp]:please enter right file name\n" );
return ;
}
if ( ( fp = fopen( cName, "rb" ) ) == NULL )
{
printf( "load bitmap false \n" );
return ;
}
fread( &fileheader, sizeof( fileheader), 1, fp ); // read bmp file header information
fread( &infoheader, sizeof( infoheader), 1, fp ); // read bmp info header informaiton
G_nPicWidth = infoheader.bWidth; // picture width
G_nPicHeight = infoheader.bHeight; // picture height
LineBytes = ( G_nPicWidth * 24 + 31) / 32 * 4;
if ( fileheader.bType != 0x4D42 ) // check picture is or not bmp
{
printf( "this pic is not bmp\n" );
fclose(fp);
fp = NULL ;
return ;
}
if ( infoheader.bCompression == 1 ) // check picture is or not compression
{
printf( "this pic is Compression\n" );
fclose(fp);
fp = NULL ;
return ;
}
fseek( fp, fileheader.bOffset, 0 );
G_cpPicRGB_Data = (unsigned char *)(malloc(G_nPicHeight * G_nPicWidth * 3 ));
for ( ni = 0 ; ni < G_nPicHeight ; ni ++ )
{
for ( nj = 0 ; nj < G_nPicWidth ; nj ++ )
{
fread( G_cpPicRGB_Data + ((ni * G_nPicWidth) + nj) *3 , 1, 1, fp ) ;
fread( G_cpPicRGB_Data + ((ni * G_nPicWidth) + nj) *3 + 1, 1, 1, fp ) ;
fread( G_cpPicRGB_Data + ((ni * G_nPicWidth) + nj) *3 + 2, 1, 1, fp ) ;
}
if ( (LineBytes - G_nPicWidth * 3) > 0 )
{
fread(PadZeros, sizeof(unsigned char), (LineBytes - G_nPicWidth * 3), fp);
}
}
fclose(fp);
fp = NULL ;
}
/*把全局变量G_cpPicRGB_Data中的RGB数据写入文件并保存*/
void SaveBmp ( char *cName )
{
FILE *fp1 = 0;
int ni = 0;
int nj = 0;
int size = 0;
int LineBytes ;
if ( cName == NULL )
{
printf( "[SaveBmp]:please enter right file name \n" );
return ;
}
fp1 = fopen( cName, "wb" );
if ( fp1 == NULL )
{
printf( "[SaveBmp]:open file false\n" );
return ;
}
LineBytes = ( G_nPicWidth * 24 + 31) / 32 * 4;
size = fwrite( &fileheader, sizeof(fileheader), 1, fp1 );
size = fwrite( &infoheader, sizeof(infoheader), 1, fp1 );
for ( ni = 0 ; ni < G_nPicHeight; ni ++ )
{
for ( nj = 0 ; nj < G_nPicWidth ; nj ++ )
{
fwrite( G_cpPicRGB_Data + ((ni * G_nPicWidth) + nj) * 3 , 1, 1, fp1 ) ;
fwrite( G_cpPicRGB_Data + ((ni * G_nPicWidth) + nj) * 3 + 1, 1, 1, fp1 ) ;
fwrite( G_cpPicRGB_Data + ((ni * G_nPicWidth) + nj) * 3 + 2, 1, 1, fp1 ) ;
}
if ( (LineBytes - G_nPicWidth * 3) > 0 )
{
fwrite(G_cpPicRGB_Data + ((ni * G_nPicWidth) + nj) * 3 + 3, sizeof(unsigned char),
(LineBytes - G_nPicWidth * 3), fp1);
}
}
fclose( fp1 );
fp1 = NULL;
}
/*从全局变量G_cpPicRGB_Data中获取RGB三个分量存放在PicData类型的结构体pPic_RGBStruct_Data_out(输出参数)中*/
void Get_Pic_RGBStruct_Data(PicData * pPic_RGBStruct_Data_out)
{
int i,j;
BYTE * pPicRGBData = G_cpPicRGB_Data;
for (i=0; i < G_nPicHeight; i++)
for (j=0; j < G_nPicWidth; j++)
{
pPic_RGBStruct_Data_out->R = *(pPicRGBData++);
pPic_RGBStruct_Data_out->G = *(pPicRGBData++);
pPic_RGBStruct_Data_out->B = *(pPicRGBData++);
pPic_RGBStruct_Data_out++;
}
}
/*从PicData类型的结构体pPic_RGBStruct_Data_in(输入参数)中获取RGB数据存放到G_cpPicRGB_Data*/
void Set_Pic_Data(PicData * pPic_RGBStruct_Data_in)
{
int i,j;
BYTE * pPicRGBData = G_cpPicRGB_Data;
for (i=0; i < G_nPicHeight; i++)
for (j=0; j < G_nPicWidth; j++)
{
*(pPicRGBData++) = pPic_RGBStruct_Data_in->R;
*(pPicRGBData++) = pPic_RGBStruct_Data_in->G;
*(pPicRGBData++) = pPic_RGBStruct_Data_in->B;
pPic_RGBStruct_Data_in++;
}
}
/*输入参数pPic_RGBStruct_Data_in中PicData类型的数据对应的RGB分量转化为YUV*/
void RGB2YUV(double* imageY, double* imageU, double* imageV, PicData* pPic_RGBStruct_Data_in)
{
int i=0;
for (i=0; i< G_nPicWidth*G_nPicHeight;i++)
{
*(imageY) = 0.257*pPic_RGBStruct_Data_in->R + 0.504*pPic_RGBStruct_Data_in->G +
0.098*pPic_RGBStruct_Data_in->B + 16;
*(imageU) = -0.148*pPic_RGBStruct_Data_in->R - 0.291*pPic_RGBStruct_Data_in->G +
0.439*pPic_RGBStruct_Data_in->B + 128;
*(imageV) = 0.439*pPic_RGBStruct_Data_in->R - 0.368*pPic_RGBStruct_Data_in->G -
0.071*pPic_RGBStruct_Data_in->B + 128;
*(imageY) += 0.5;
*(imageU) += 0.5;
*(imageV) += 0.5;
*(imageY) = Clamp(*imageY,0,255);
*(imageU) = Clamp(*imageU,0,255);
*(imageV) = Clamp(*imageV,0,255);
pPic_RGBStruct_Data_in++;
imageY++;
imageU++;
imageV++;
}
}
/*YUV转化为RBG保存在输出参数pPic_RGBStruct_Data_out中*/
void YUV2RGB(PicData* pPic_RGBStruct_Data_out, double* imageY, double* imageU, double* imageV)
{
int i=0;
for (i=0; i< G_nPicWidth*G_nPicHeight;i++)
{
double r,g,b;
r = (1.164*(*imageY-16) + 1.596 * ((*imageV) - 128));
g = (1.164*(*imageY-16) - 0.813 * ((*imageV) - 128) - 0.391 * ((*imageU) - 128));
b = (1.164*(*imageY-16) + 2.018 * ((*imageU) - 128));
r +=0.5;
g +=0.5;
b +=0.5;
pPic_RGBStruct_Data_out->R = (BYTE)Clamp(r,0,255);
pPic_RGBStruct_Data_out->G = (BYTE
- 1
- 2
- 3
前往页