CAFE

C++

색상 변환 함수 RGB, GRAY, CMY, HSV, HLS

작성자수알치|작성시간09.12.12|조회수2,098 목록 댓글 0

<출처: 마이크로소프트웨어>

 

/* List : ColorModel.c

    If you want to compile with original C compiler,

    you will convert from C++ comment  type to C comment type. */

 

#include <stdio.h>
#include <conio.h>

#include "ColorModel.h"

#define MAX(a, b)  (((a) > (b)) ? (a) : (b))
#define MIN(a, b)  (((a) < (b)) ? (a) : (b))

#define UNDEFINED (0.0)


//////////////////////////////////////////////////////////////////////////////////
// RGB_To_Gray - RGB값을 Gray로 바꾼다.
//
// Gray 는 각각 [0,1]사이 값을 갖는다.
// R,G,B는 각각 [0,1]사이 값을 갖는다.

void RGB_To_Gray(double r, double g, double b, double *gray)
{
  *gray = r * 0.30 + g * 0.59 + b * 0.11;
}

//////////////////////////////////////////////////////////////////////////////////
// Gray_To_RGB - Gray 값을 RGB로 바꾼다.
//               이과정은 promotion에 해당하는 과정으로 사실상 별의미가 없다.
// Gray 는 각각 [0,1]사이 값을 갖는다.
// R,G,B는 각각 [0,1]사이 값을 갖는다.

void Gray_To_RGB(double gray, double *r, double *g, double *b)
{
  *r = *g = *b = gray;
}

//////////////////////////////////////////////////////////////////////////////////
// CMY_To_RGB - CMY값을 RGB로 바꾼다.
//
// R,G,B는 각각 [0,1]사이 값을 갖는다.
// C,M,Y는 각각 [0,1]사이 값을 갖는다.

void RGB_To_CMY(double r, double g, double b, double *c, double *m, double *y)
{
  *c = 1.0 - r;
  *m = 1.0 - g;
  *y = 1.0 - b;
}


//////////////////////////////////////////////////////////////////////////////////
// CMY_To_RGB - CMY값을 RGB로 바꾼다.
//
// R,G,B는 각각 [0,1]사이 값을 갖는다.
// C,M,Y는 각각 [0,1]사이 값을 갖는다.

void CMY_To_RGB(double c, double m, double y, double *r, double *g, double *b)
{
  *r = 1.0 - c;
  *g = 1.0 - m;
  *b = 1.0 - y;
}


//////////////////////////////////////////////////////////////////////////////////
// RGB_To_HSV - RGB값을 HSV로 바꾼다.
//
// R,G,B는 각각 [0,1]사이 값을 갖는다.
// H는 [0,360) 범위, S,V값은 각각 [0,1]범위를 갖는다.

void RGB_To_HSV(double r, double g, double b, double *h, double *s, double *v)
{
  double max, min;
   
  max = MAX(r,g);
  max = MAX(max,b);

  min = MIN(r,g);
  min = MIN(min,b);

  *v = max;                                   // 명도(V) = max(r,g,b)
  *s = (max != 0.0) ? (max-min)/max : 0.0;    // 채도(S)을 계산, S=0이면 R=G=B=0

  if(*s == 0.0)
    *h = UNDEFINED;
  else {                                      // 채도(S)는 != 0
    double delta = max - min;                 // 색상(H)를 구한다.

    if(r == max)
      *h = (g - b) / delta;                   // 색상이 Yello와 Magenta사이
    else if( g == max)
      *h = 2.0 + (b - r) / delta;             // 색상이 Cyan와 Yello사이
    else if( b == max)
      *h = 4.0 + (r - g) / delta;             // 색상이 Magenta와 Cyan사이

    *h *= 60.0;

    if(*h < 0.0)                              // 색상값을 각도로 바꾼다.
      *h += 360.0;
  }
}


//////////////////////////////////////////////////////////////////////////////////
// HSV_To_RGB - HSV값을 RGB로 바꾼다.
//
// H는 [0,360) 범위, S,V값은 각각 [0,1]범위를 갖는다.
// R,G,B는 각각 [0,1]값을 갖는다.

void HSV_To_RGB(double h, double s, double v, double *r, double *g, double *b)
{
  if(s == 0.0)                                // 컬러값은 흑백명암값.
  {
    if(h == UNDEFINED)                        // 이경우 색상 값은 없다.
      *r = *g = *b = v;
    else
      *r = *g = *b = UNDEFINED;
  } else
  {                                           // S != 0 이므로 색상(H)이 있다.
    double f, p, q, t;
    int i;

    if(h == 360.0)
      h = 0.0;

    h /= 60.0;                                 // H 값은 [0,360)사이 값
    i = (int)h;                                // <=H 인 가장 큰 정수값
    f = h - i;                                 // F 는 H 의 실수 부분
    p = v * (1.0 - s);
    q = v * (1.0 - (s * f));
    t = v * (1.0 - (s * (1.0 - f)));

    switch(i)
    {
    case 0: *r = v; *g = t; *b = p; break;
    case 1: *r = q; *g = v; *b = p; break;
    case 2: *r = p; *g = v; *b = t; break;
    case 3: *r = p; *g = q; *b = v; break;
    case 4: *r = t; *g = p; *b = v; break;
    case 5: *r = v; *g = p; *b = q; break;
    }
  }
}


//////////////////////////////////////////////////////////////////////////////////
// RGB_To_HLS - RGB값을 HLS로 바꾼다.
//
// R,G,B는 각각 [0,1]값을 갖는다.
// H는 [0,360) 범위, S,V값은 각각 [0,1]범위를 갖는다.

void RGB_To_HSL(double r, double g, double b, double *h, double *s, double *l)
{
  double v;
  double m;
  double vm;
  double r2, g2, b2;

  v = MAX(r,g);
  v = MAX(v,b);
  m = MIN(r,g);
  m = MIN(m,b);

  if ((*l = (m + v) / 2.0) <= 0.0)
    return;
  if ((*s = vm = v - m) > 0.0) {
  *s /= (*l <= 0.5) ? (v + m ) : (2.0 - v - m) ;
  } else
   return;

  r2 = (v - r) / vm;
  g2 = (v - g) / vm;
  b2 = (v - b) / vm;

  if (r == v)
    *h = (g == m ? 5.0 + b2 : 1.0 - g2);
  else if (g == v)
  *h = (b == m ? 1.0 + r2 : 3.0 - b2);
  else
  *h = (r == m ? 3.0 + g2 : 5.0 - r2);

  *h *= 60.0;
}


//////////////////////////////////////////////////////////////////////////////////
// HLS_To_RGB - HLS값을 RGB로 바꾼다.
//
// H는 [0,360) 범위, S,V값은 각각 [0,1]범위를 갖는다.
// R,G,B는 각각 [0,1]값을 갖는다.


void HSL_To_RGB(double h, double sl, double l, double *r, double *g, double *b)
{
  double v;

  v = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
  if (v <= 0) {
   *r = *g = *b = 0.0;
  } else
  {
   double m;
   double sv;
   int sextant;
   double fract, vsf, mid1, mid2;

   m = l + l - v;
   sv = (v - m ) / v;
   h /= 60.0;
   sextant = (int)h; 
   fract = h - sextant;
   vsf = v * sv * fract;
   mid1 = m + vsf;
   mid2 = v - vsf;

   switch (sextant) {
    case 0: *r = v;    *g = mid1; *b = m; break;
    case 1: *r = mid2; *g = v;    *b = m; break;
    case 2: *r = m;    *g = v;    *b = mid1; break;
    case 3: *r = m;    *g = mid2; *b = v; break;
    case 4: *r = mid1; *g = m;    *b = v; break;
    case 5: *r = v;    *g = m;    *b = mid2; break;
   }
  }
}


// 간단한 테스트 프로그램
//

main()
{
  double a, b, c;

  RGB_To_HSV( 0.60, 0.20, 0.30, &a, &b, &c );
  printf( "RGB(0.60, 0.20, 0.30) -> HSV(%.2f, %.2f, %.2f)\n", a, b, c );

  HSV_To_RGB( 345.0, 0.67, 0.60, &a, &b, &c );
  printf( "HLS(345.0, 0.67, 0.60) -> RGB(%.2f, %.2f, %.2f)\n", a, b, c );

  RGB_To_HSL( 0.30, 0.40, 0.80, &a, &b, &c );
  printf( "RGB(0.30, 0.40, 0.80) -> HSL(%.2f, %.2f, %.2f)\n", a, b, c );

  HSL_To_RGB(228.0, 0.55, 0.56, &a, &b, &c );
  printf( "HSL(228.0, 0.55, 0.56) -> RGB(%.2f, %.2f, %.2f)\n", a, b, c );

  return 0;
}

-------------------------------------------------------------------------------------

 

/* List : ColorModel.h                                 */

 

void RGB_To_Gray(double r, double g, double b, double *gray);
void Gray_To_RGB(double gray, double *r, double *g, double *b);
void RGB_To_CMY(double r, double g, double b, double *c, double *m, double *y);
void CMY_To_RGB(double c, double m, double y, double *r, double *g, double *b);
void RGB_To_HSV(double r, double g, double b, double *h, double *s, double *v);
void HSV_To_RGB(double h, double s, double v, double *r, double *g, double *b);
void RGB_To_HSL(double r, double g, double b, double *h, double *l, double *s);
void HSL_To_RGB(double h, double l, double s, double *r, double *g, double *b);

 

/* The End */

 

 

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼