IDL/Direct Graphics

DG 체계에서 컬러테이블에 없는 색상 사용하기

이상우_idl 2022. 6. 17. 16:58
728x90
반응형

DG(Direct Graphics) 체계에서 특정한 색상(Color)을 사용하고자 할 경우에는 그 색상이 포함되어 있는 컬러테이블을 불러와서 그 색상의 번호(Index)를 명시하는 사용하는 방법이 일반적입니다. 예를 들어 빨간색(Red)을 사용하고자 할 경우 다음과 같이 이 색상을 포함하는 컬러테이블(예를 들면 13번)을 불러온 다음 색상 번호 255를 사용하는 방식입니다.

 

LOADCT, 13

XYOUTS, 0.5, 0.5, 'IDL', COLOR=255, /NORMAL

 

그런데 작업을 하다보면 컬러테이블에 속한 256개의 색상들 외에 다른 색상을 사용하는 것이 필요할 경우가 있습니다. 앞서 예를 들었던 13번 컬러테이블의 경우 그 색상 구성을 보면 다음과 같습니다.

 

 

이 모습을 보면 금방 알 수 있는데 실제로 13번 컬러테이블에는 흰색(White)이 존재하지 않는다는 것입니다. 하지만 모종의 이유로 이 13번 컬러테이블을 반드시 사용해야 하는데 그러면서도 흰색도 사용해야 할 경우를 가정해보는 것입니다. 예를 들면 그래픽창의 배경색을 흰색으로 처리해야 한다든지 할 경우입니다. 일단 이러한 경우를 가정하여 작성해본 예제 프로그램은 다음과 같습니다.

 

img = HANNING(300, 300)
WINDOW, XSIZE=600, YSIZE=600, RETAIN=2

DEVICE, DECOMPOSED=0
LOADCT, 13
CONTOUR, img, COLOR=0, BACKGROUND=255, $
  POSITION=[0.1, 0.1, 0.9, 0.9]
TV_OVER, BYTSCL(img)
CONTOUR, img, COLOR=0, THICK=2, /OVERPLOT
XYOUTS, 0.5, 0.83, 'My Data', COLOR=255, /NORMAL, $
  CHARSIZE=2, ALIGNMENT=0.5

 

여기서는 가상의 2차원 데이터에 대한 등위선(Contour)과 이미지를 DG 체계 기반으로 중첩 표출하기 위하여 CONTOUR 프로시저 뿐 아니라 제가 예전에 소개해드렸던 TV_OVER 프로시저도 함께 사용하였습니다(TV_OVER 프로시저의 소스 프로그램은 이 게시물에서 다운로드받으실 수 있습니다). 또한 XYOUTS 프로시저를 사용하여 캡션 문자를 그림 내에 삽입하였습니다. 표출된 그림은 다음과 같습니다.

 

 

여기서 등위선 그림의 XY축 및 눈금 문자 등은 검정색(0번 색상)으로 표시되어 있습니다. 다만 배경색상은 255번 색상인 빨간색을 그냥 사용한 상태입니다. 흰색이 없기 때문에 고육지책으로 일단 255번 색상으로 처리해놓은 상태인데요. 캡션 문자도 마찬가지입니다. 따라서 이 모습이 최종 목표는 아닙니다. 궁극적으로는 그래픽창의 배경 색상과 캡션 문자의 색상을 흰색으로 처리해보고자 하는 것이 목표입니다. 하지만 13번 컬러테이블을 사용하는 상태에서는 그렇게 처리하는 것이 어려운 상황인데요. 물론 해결 방법은 몇가지가 있습니다. 그 방법을 하나씩 살펴보겠습니다.

 

< 방법 1 >

 

첫번째 방법은 현재 사용중인 13번 컬러테이블 내에 흰색을 우겨넣는(?) 방법입니다. 이를 위하여 TVLCT 명령을 사용하면 되는데, 그 방식은 다음과 같습니다.

 

img = HANNING(300, 300)
WINDOW, XSIZE=600, YSIZE=600, RETAIN=2

DEVICE, DECOMPOSED=0
LOADCT, 13

TVLCT, 255, 255, 255, 255
CONTOUR, img, COLOR=0, BACKGROUND=255, $
  POSITION=[0.1, 0.1, 0.9, 0.9]
TV_OVER, BYTSCL(img)
CONTOUR, img, COLOR=0, THICK=2, /OVERPLOT
XYOUTS, 0.5, 0.83, 'My Data', COLOR=255, /NORMAL, $
  CHARSIZE=2, ALIGNMENT=0.5

 

이와 같이 LOADCT 명령으로 13번 컬러테이블을 불러온 직후에 TVLCT 명령을 사용하여, 13번 컬러테이블의 255번 색상을 RGB값이 [255, 255, 255]인 흰색으로 대체하는 것입니다. 이렇게 처리할 경우의 표출 결과는 다음과 같습니다.

 

 

그런데 뭔가 좀 이상하죠? 일단 배경색 및 캡션 문자의 색상을 흰색으로 처리하는 것은 성공했지만, 이미지의 모습을 보면 배열 값이 가장 높은 정가운데 영역이 흰색으로 처리되었음을 볼 수 있습니다. 왜냐하면 컬러테이블 내에서 가장 높은 색상값인 255가 이러한 영역을 나타내게 되는데, TVLCT 명령의 사용에 의하여 255가 흰색이 되어버렸기 때문입니다. 따라서 이러한 문제를 해결하기 위하여 배열 img에 대하여 BYTSCL 함수를 사용하여 바이트스케일링을 할 때 다음과 같이 처리해봅시다. 즉 위의 내용에서 TV_OVER 명령이 사용된 부분만 다음과 같이 수정하여 다시 실행해봅시다.

 

TV_OVER, BYTSCL(img, TOP=254)

 

그러면 결과는 다음 그림과 같습니다.

 

 

이와 같이 배열 값이 높은 부분에서 흰색 구멍이 나타나는 문제는 해결되었는데요. 여기서는 BYTSCL 함수를 사용할 때 TOP 키워드의 값을 254로 설정함으로써, 컬러테이블 내에서 0~255 대신 0~254 범위 색상들만 사용하도록 한 것입니다. 따라서 앞서 우리가 TVLCT 명령으로 흰색으로 바꿔놓은 255번 색상은 이미지의 표출에서는 사용되지 않도록 처리한 것입니다. 물론 컬러테이블 내에서 색상값 하나를 희생한 것이긴 하지만 이 정도면 나쁘지 않은 거래라고 봅니다.

 

< 방법 2 >

 

두번째 방법은 여러 컬러테이블들을 교차 활용하는 방법입니다. 즉 그래픽 명령을 사용할 때마다 거기서 필요로 하는 색상이 포함된 컬러테이블을 불러와서 사용하는 방식인데요. 우리가 필요로 하는 흰색을 포함하고 있는 0번 컬러테이블을 13번 컬러테이블과 병행 사용하는 것입니다. 그 방식은 다음과 같습니다.

 

img = HANNING(300, 300)
WINDOW, XSIZE=600, YSIZE=600, RETAIN=2

DEVICE, DECOMPOSED=0
LOADCT, 0
CONTOUR, img, COLOR=0, BACKGROUND=255, $
  POSITION=[0.1, 0.1, 0.9, 0.9]
LOADCT, 13
TV_OVER, BYTSCL(img)
LOADCT, 0
CONTOUR, img, COLOR=0, THICK=2, /OVERPLOT
XYOUTS, 0.5, 0.83, 'My Data', COLOR=255, /NORMAL, $
    CHARSIZE=2, ALIGNMENT=0.5

 

이와 같이 이미지를 표출할 때에만 13번 컬러테이블을 불러와서 사용하고, 나머지 표출 과정에서는 0번 컬러테이블을 사용하는 것입니다. 이 방법을 사용하면 앞서 방법 1에서와 같이 굳이 색상값 하나를 희생할 필요는 없게 됩니다. 다만 적시에 서로 다른 컬러테이블을 불러오는 것이 약간 귀찮을 수는 있습니다. 어쨌든 결과는 다음 그림과 같습니다.

 

 

< 방법 3 >

 

세번째 방법은 별도로 필요한 단일 색상을 16진수 방식의 RGB 색상으로 명시하는 방법입니다. 이 방법에 관해서는 제가 예전에 관련게시물을 올린 바 있으므로, 여기서는 이 방법에 관한 자세한 설명은 생략하기로 합니다. 일단 이 방식을 적용하면 다음과 같습니다.

 

img = HANNING(300, 300)
WINDOW, XSIZE=600, YSIZE=600, RETAIN=2

DEVICE, DECOMPOSED=1
CONTOUR, img, COLOR='000000'x, BACKGROUND='FFFFFF'x, $
  POSITION=[0.1, 0.1, 0.9, 0.9]
DEVICE, DECOMPOSED=0
LOADCT, 13
TV_OVER, BYTSCL(img)
DEVICE, DECOMPOSED=1
CONTOUR, img, COLOR='000000'x, THICK=2, /OVERPLOT
XYOUTS, 0.5, 0.83, 'My Data', COLOR='FFFFFF'x, /NORMAL, $
  CHARSIZE=2, ALIGNMENT=0.5

 

이와 같이 13번 컬러테이블의 사용이 필요한 시점에서만 DECOMPOSED를 0으로 설정한 후 이 컬러테이블을 불러와서 사용하고, 컬러테이블에 없는 단일 색상이 필요한 부분들에서는 DECOMPOSED를 1로 설정한 상태에서 16진수 방식의 RGB 색상으로 명시하여 사용하는 것입니다. 결과는 다음과 같습니다. 어차피 바로 앞선 결과 그림과 똑같습니다.

 

 

사실 이 방법도 매번 필요할 때마다 DECOMPOSED를 1로 설정하고 16진수 컬러를 명시해야한다는 약간의 불편함이 따르긴 합니다. 그 대신 이 방법의 장점은 필요한 특정한 단일 색상이 포함된 다른 컬러테이블 및 색상값을 일부러 찾아헤메야 할 필요는 없다는 것입니다. 그 예제로서 앞선 내용을 다음과 같이 살짝 수정해봅시다.

 

img = HANNING(300, 300)
WINDOW, XSIZE=600, YSIZE=600, RETAIN=2

DEVICE, DECOMPOSED=1
CONTOUR, img, COLOR='000000'x, BACKGROUND='CBC0FF'x, $
  POSITION=[0.1, 0.1, 0.9, 0.9]
DEVICE, DECOMPOSED=0
LOADCT, 13
TV_OVER, BYTSCL(img)
DEVICE, DECOMPOSED=1
CONTOUR, img, COLOR='000000'x, THICK=2, /OVERPLOT
XYOUTS, 0.5, 0.83, 'My Data', COLOR='FFFF00'x, /NORMAL, $
  CHARSIZE=2, ALIGNMENT=0.5

 

여기서는 배경의 색상을 핑크(Pink : [255, 192, 203] --> 'CBC0FF'x)로 처리하고 캡션문자의 색상을 시안(Cyan : [0, 255, 255] --> 'FFFF00'x)으로 처리하였습니다. 결과는 다음 그림과 같습니다.

 

 

여기서 특정한 단일 색상을 16진수 컬러값으로 바꾸는 방법에 관해서는 앞서 소개한 링크를 알려드린 관련게시물의 내용을 참조하시기 바랍니다.

 

< DG 말고 NG에서는? >

 

컬러테이블에 존재하지 않는 별도의 색상을 사용한다는 것이 DG 체계에서는 앞서 제시된 것과 같이 몇가지 다소 귀찮은 방법들을 사용해야만 가능하지만 사실 NG 체계에서는 꽤 간편하게 처리가 가능합니다. 바로 앞서 표출했던 것과 같은 그림을 NG 체계에서 구현하는 과정 및 표출 그림은 대략 다음과 같습니다.

 

win = WINDOW(DIMENSIONS=[600, 600], /NO_TOOLBAR, $
  BACKGROUND_COLOR='pink')
i = IMAGE(img, RGB_TABLE=13, AXIS_STYLE=2, $
  XTICKINTERVAL=100, YTICKINTERVAL=100, $
  MARGIN=0.1, /CURRENT)
c = CONTOUR(img, N_LEVELS=4, COLOR='black', C_THICK=2, $
  C_LABEL_SHOW=0, /OVERPLOT)
t = TEXT(0.5, 0.83, 'My Data', COLOR='cyan', FONT_SIZE=16, $
  ALIGNMENT=0.5, /NORMAL)

 

 

이와 같이 컬러테이블과 다른 단일 색상들을 사용하는데 있어서 별다른 설정들을 신경쓸 필요는 없이 그냥 바로 갖다 사용하면 됩니다. 물론 NG와 DG 각각 나름의 장단점이 있고, 현장에서는 둘 중 하나의 그래픽 체계에서만 작업을 해야 할 경우도 많습니다. 따라서 DG 체계에서 작업해야 하는 상황에서 컬러테이블과 별도의 단일 색상을 함께 사용하는데 있어서 난관에 봉착하시게 된다면 오늘 소개된 방법으로 해결을 해보시면 좋을 것 같습니다.

 

반응형