|
typedef struct {あらかじめ、pixel構造体に1画素分のRGBを入れるものとする。
unsigned char B;
unsigned char R;
unsigned char G;
} RGB;
RGB pixel;実際の変換処理は、次のようになる。
fread(&pixel, sizeof(RGB), 1, fp); /* BMPから1画素読む */
double Y, Cb, Cr;これを関数化するなどすると、RGBとYの変更分を与えるだけで目的のRGBを得る処理とすることができる。
double R, G, B;
R = pixel.R;
G = pixel.G;
B = pixel.B;
/* Y/Cb/Crを求める */
/* 飽和演算だが、ここでは敢えてマクロ等を使わず説明 */
Y = 0.299*R + 0.587*G + 0.114*B;
Cb = -0.169*R - 0.332*G + 0.5*B + 128.0;
Cr = 0.5*R - 0.419*G - 0.081*B + 128.0;
Y += kidoChange; /* kidoChangeは-255…0…+255の範囲内 */
if (Y < 0.0) Y = 0.0;
if (Y > 255.0) Y = 255.0;
if (Cb < 0.0) Cb = 0.0;
if (Cb > 255.0) Cb = 255.0;
if (Cr < 0.0) Cr = 0.0;
if (Cr > 255.0) Cr = 255.0;
/* 計算されたY/Cb/Crから、新たなRGBを算出する */
/* 飽和演算だが、ここでは敢えてマクロ等を使わず説明 */
Cb -= 128.0;
Cr -= 128.0;
R = Y + (1.402 * Cr);
if (R < 0.0) R = 0.0;
if (R > 255.0) R = 255.0;
G = Y - (0.344 * Cb) - (0.714 * Cr);
if (G < 0.0) G = 0.0;
if (G > 255.0) G = 255.0;
B = Y + (1.772 * Cb);
if (B < 0.0) B = 0.0;
if (B > 255.0) B = 255.0;
/* 足している 0.00001 は、整数変換時の誤差の解消用 */
pixel.R = (unsigned char)(R + 0.00001);
pixel.G = (unsigned char)(G + 0.00001);
pixel.B = (unsigned char)(B + 0.00001);