[ create a new paste ] login | about

Link: http://codepad.org/YwgJpPli    [ raw code | output | fork ]

C, pasted on Nov 19:
#include <stdio.h>
#include <stdlib.h>

#pragma pack(push,2)
typedef struct tagBITMAPFILEHEADER {
        unsigned short	bfType;
        unsigned long   bfSize;
        unsigned short	bfReserved1;
        unsigned short	bfReserved2;
        unsigned long	bfOffBits;
} BITMAPFILEHEADER;
#pragma pack(pop)

#pragma pack(push,4)
typedef struct tagBITMAPINFOHEADER{
        unsigned long	biSize;
        long			biWidth;
        long			biHeight;
        unsigned short	biPlanes;
        unsigned short	biBitCount;
        unsigned long	biCompression;
        unsigned long	biSizeImage;
        long			biXPelsPerMeter;
        long			biYPelsPerMeter;
        unsigned long	biClrUsed;
        unsigned long	biClrImportant;
} BITMAPINFOHEADER;
#pragma pack(pop)

#pragma pack(push,1)
// ピクセル(BGRの順であることに注意)
typedef struct{
unsigned char b;//(0-255)
unsigned char g;//(0-255)
unsigned char r;//(0-255)
} PIXEL ;

// HSV
typedef struct{
	unsigned int h;	//(0-359)
	unsigned char s;//(0-255)
	unsigned char v;//(0-255)
}HSV;
#pragma pack(pop)


// イメージデータ構造体
typedef struct{
	BITMAPFILEHEADER bmpFile ;
	BITMAPINFOHEADER bmpInfo ;
	PIXEL* pixel ;
	unsigned int pixel_count ;
} IMAGE_DATA ;


// ビットマップデータ読み取り
int ReadBitmapImage ( char* img_file, IMAGE_DATA* image )
{
	FILE *bmp;
	
	// ファイルオープン
	bmp = fopen ( img_file, "rb" ) ;
	if ( bmp==NULL ){
		printf ( "Can't open %s\n", img_file ) ;
		return 0 ;
	}

	// ヘッダー読み取り
	fread ( &image->bmpFile, sizeof(BITMAPFILEHEADER), 1, bmp ) ;
	fread ( &image->bmpInfo, sizeof(BITMAPINFOHEADER), 1, bmp ) ;	

	// 24bit以外とOS/2ビットマップをはじく
	if ( image->bmpInfo.biBitCount!=24 || image->bmpInfo.biSize!=40 ){
		printf ( "only 24bit windows bitmaps are supported\n" ) ;
		return 0 ;
	}
	image->pixel_count = image->bmpInfo.biWidth*image->bmpInfo.biHeight ;// ピクセル数

	// 色データの読み取り
	image->pixel = (PIXEL*)malloc ( sizeof(PIXEL)*image->pixel_count ) ;
	fread ( image->pixel, sizeof(PIXEL), image->pixel_count, bmp ) ;
	fclose(bmp) ;

	return 1 ;
}

// ビットマップ書き出し
// delは書き出し後にピクセルデータを破棄するかしないか
void WriteBitmapData ( char* img_file, IMAGE_DATA* image, int del )
{
	FILE *outFile;
	outFile = fopen ( img_file, "wb" ) ;
	fwrite ( &image->bmpFile, sizeof(BITMAPFILEHEADER), 1, outFile ) ;
	fwrite ( &image->bmpInfo, sizeof(BITMAPINFOHEADER), 1, outFile ) ;	
	fwrite ( image->pixel, sizeof(PIXEL), image->pixel_count, outFile ) ;
	fclose(outFile) ;

	// ピクセルデータ破棄
	if ( del ){
		free (image->pixel) ;
	}
}

// RGBからVSHへ変換
void RGBtoHSV ( const PIXEL* pixel, HSV* vsh )
{
	unsigned char max, min ;
	double h ;

	max = pixel->r; if(max<pixel->g)max=pixel->g; if(max<pixel->b)max=pixel->b;
	min = pixel->r; if(min>pixel->g)min=pixel->g; if(min>pixel->b)min=pixel->b;

	vsh->v = max ;
	if ( max==0 ){
		vsh->s = 0 ;
		vsh->h = 0 ;
	} else {
		vsh->s = (unsigned char)(255.0*(max - min)/(double)max);

		h = 1.0/(double)(max - min) ;
		if( max==pixel->r ){
			h = h*(double)(pixel->g-pixel->b) ;
		} else if ( max==pixel->g ){
			h = h*(double)(pixel->b-pixel->r) + 2 ;
		} else {
			h = h*(double)(pixel->r-pixel->g) + 4 ;
		}
		h *= 60;
		if(h < 0) h += 360;
		vsh->h = (unsigned int)h;
	}
}

// VSHからRGBへ変換
void HSVtoRGB ( const HSV* vsh, PIXEL* pixel )
{
	int I, M, N, K;
	double F;

	if ( vsh->s==0 ){
		pixel->r = pixel->g = pixel->b = vsh->v ;
	} else {
		I = (int)(vsh->h/60.0);
		F = vsh->h/60.0 - I;
		M = (int)(vsh->v*(1.0 - vsh->s/255.0));
		N = (int)(vsh->v*(1.0 - (vsh->s/255.0) * F));
		K = (int)(vsh->v*(1.0 - (vsh->s/255.0) * (1.0-F)));

		switch(I){
			case 0:
				pixel->r = vsh->v;
				pixel->g = K;
				pixel->b = M;
				break;
			case 1:
				pixel->r = N;
				pixel->g = vsh->v;
				pixel->b = M;
				break;
			case 2:
				pixel->r = M;
				pixel->g = vsh->v;
				pixel->b = K;
				break;
			case 3:
				pixel->r = M;
				pixel->g = N;
				pixel->b = vsh->v;
				break;
			case 4:
				pixel->r = K;
				pixel->g = M;
				pixel->b = vsh->v;
				break;
			case 5:
				pixel->r = vsh->v;
				pixel->g = M;
				pixel->b = N;
		}
	}
}

// 輝度変換
void ConvPastel ( IMAGE_DATA* image )
{
	unsigned int i ;
	HSV hsv ;

	// 輝度:元色(0.0)~白(1.0)
	double l = 0.4;

	for( i = 0 ; i < image->pixel_count ; i++ ){
		RGBtoHSV ( image->pixel+i, &hsv ) ;
		hsv.h = hsv.h ;
		hsv.s = hsv.s-(unsigned char)(hsv.s*l) ;
		hsv.v = hsv.v + (unsigned char)((255-hsv.v)*l) ;
		HSVtoRGB  ( &hsv, image->pixel+i ) ;
	}
}

int main ( void )
{
	IMAGE_DATA image ;

	// 読み取り
	if ( !ReadBitmapImage ( "test.bmp", &image ) ){
		printf ( "Error\n" ) ;
		return 1 ;
	}

	// 変換
	ConvPastel ( &image ) ;

	// 書き出し
	WriteBitmapData ( "view.bmp", &image, 1 ) ;

	return 0 ;
}


Output:
1
2
Can't open test.bmp
Error


Create a new paste based on this one


Comments: