IDL/Direct Graphics

DG 체계에서 RGB 색상 사용법

이상우_idl 2022. 1. 25. 14:32
728x90
반응형

오늘은 단일 색상을 설정하는데 있어서 DG(Direct Graphics) 체계에서 RGB 방식으로 색상을 설정하는 방법을 소개해보고자 합니다. 이게 무슨 얘기냐 하면, NG(New Graphics) 체계에서는 단일 색상을 설정하는데 있어서 예를 들면 다음과 같은 방법들이 제공됩니다.

 

tx = TEXT(0.5, 0.5, 'IDL', COLOR='red', /NORMAL)

tx = TEXT(0.5, 0.5, 'IDL', COLOR=[255, 0, 0], /NORMAL)

 

이와 같이 단일 색상을 색상의 고유 이름으로 설정하거나 또는 RGB 값들로 설정하는 방식이 모두 가능합니다. 편리하죠. 그런데 DG 체계의 경우는 이러한 방식의 색상 설정 기능이 없습니다(제가 알기로는 그렇습니다). 사실 DG 체계에서 특정한 단일 색상을 사용하기 위한 전통적인 방법은 다음과 같습니다.

 

1. 원하는 색상이 포함된 컬러테이블을 찾는다

2. 그 컬러테이블을 불러온다

3. 그 상태에서 해당 색상의 번호를 사용하여 색상을 반영한다

 

예를 들어 붉은색을 사용하고 싶다면 34번 컬러테이블을 불러와서 그 안에 포함된 255번 색상을 사용하는 방식입니다.

 

DEVICE, DECOMPOSED=0

LOADCT, 34

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

 

그런데 이 방법의 경우, 내가 원하는 색상이 어떤 컬러테이블에 존재하는지 찾기도 좀 번거롭고, 특정한 컬러테이블을 찾아서 로드해놓으면 그 컬러테이블에는 존재하지 않는 다른 색상의 사용이 제한될 수도 있는 등의 단점이 있는 것도 사실입니다. 그냥 DG 체계에서도 NG 체계에서와 같이 편리하고 직관적으로 특정한 색상을 선택하여 사용할 수는 없을까요? 사실 방법이 전혀 없지는 않습니다. 다만 그 과정이 약간 번거로울 뿐입니다. 물론 그렇다고 엄청나게 복잡한 것도 아닙니다. 어쨌든 그 방법을 지금부터 알아보도록 하겠습니다.

 

일단 다음과 같이 DG 체계 기반의 예제 플롯을 하나 표출해보겠습니다. 여기서는 배경색이 흰색이 되도록 하고 플롯의 축 및 눈금 등은 검정색으로 처리하였습니다. 다만 플롯 라인 자체 및 캡션 문자의 경우는 34번 컬러테이블에 있는 색상들을 사용하여 처리하였습니다. 이 과정에서 색상 설정에 있어서는 앞서 언급했던 전통적인 방법을 사용하였습니다.

 

x = FINDGEN(100)
y = SQRT(x)
DEVICE, DECOMPOSED=0
WINDOW, XSIZE=600, YSIZE=500, RETAIN=2
LOADCT, 0
PLOT, x, y, COLOR=0, BACKGROUND=255, $
  CHARSIZE=1.4, /NODATA
LOADCT, 34
OPLOT, x, y, COLOR=32, THICK=2
XYOUTS, 60, 4, 'IDL', COLOR=255, CHARSIZE=2, CHARTHICK=2, /DATA
LOADCT, 0

 

이와 같이 34번 컬러테이블을 불러와서 32번(파란색) 및 255번(붉은색) 색상을 사용하였습니다. 표출된 그림은 다음과 같습니다.

 

 

이 과정을 보면 흰색 및 검정색을 사용하기 위하여 0번 컬러테이블을 불러왔고 푸른색 및 붉은색을 사용하기 위하여 34번 컬러테이블을 불러왔습니다. DG 체계에서는 다양한 색상들을 사용하기 위해서는 이와 같이 그 색상들이 포함된 컬러테이블을 불러와야 합니다. 그런데 이와 같은 방식 말고 그냥 특정한 색상을 바로 지정하여 사용하는 방법을 지금부터 살펴보겠습니다. 이 방법에서는 기본적으로 16진수 색상값의 개념이 사용됩니다. 갑자기 16진수가 등장해서 좀 뜬금없다는 느낌이 들 수도 있습니다. 하여간 이 방식을 보면, 예를 들어 빨간색은 RGB 값으로는 (255, 0, 0)인데 이는 16진수 색상값으로는 '0000FF'x가 됩니다. 이렇게 되는 과정은 다음과 같습니다.

 

RGB의 B값 0에 대한 16진수는 00

RGB의 G값 0에 대한 16진수는 00

RGB의 R값 255에 대한 16진수는 FF

 

이렇게 RGB를 구성하는 각 값에 대한 16진수를 역순으로 이어붙여서 0000FF가 되도록 하는 방식입니다. 이러한 방식으로 따진다면 몇몇 대표적인 색상들에 대한 16진수 색상값은 다음과 같습니다.

 

파란색 (0, 0, 255) --> 'FF0000'x

노란색 (255, 255, 0) --> '00FFFF'x

흰색 (255, 255, 255) --> 'FFFFFF'x

검은색 (0, 0, 0) --> '000000'x

 

따라서 색상을 위와 같은 16진수 값으로 설정하여 사용하면 됩니다. 앞서 표출했던 그림을 생성하는 과정을 이러한 16진수 방식으로 대체하여 다시 작성해보면 다음과 같습니다.

 

DEVICE, DECOMPOSED=1
WINDOW, XSIZE=600, YSIZE=500, RETAIN=2
PLOT, x, y, COLOR='000000'x, BACKGROUND='FFFFFF'x, $
  CHARSIZE=1.4, /NODATA
OPLOT, x, y, COLOR='FF0000'x, THICK=2
XYOUTS, 60, 4, 'IDL', COLOR='0000FF'x, CHARSIZE=2, CHARTHICK=2, /DATA

 

내용을 잘 보면 앞선 예제에서와는 달리 컬러테이블을 불러오는 부분이 전혀 없음을 알 수 있습니다. 표출 결과는 다음 그림과 같습니다.

 

 

다만 여기서 한가지 유의해야 할 것은 DEVICE 명령에서 DECOMPOSED 키워드의 값이 1이 되어야 한다는 것입니다. 즉 우리가 DG 체계에서의 작업에서 흔히 DECOMPOSED 키워드의 값을 0으로 설정하는 경우가 많지만, 지금과 같은 상황에서는 반드시 1로 설정해야 합니다. 그래야 색상값의 해석을 RGB 기반으로 하는 모드가 되고, 방금 설명한 16진수 색상값이 제대로 작동하게 됩니다.

 

그런데 방금 우리가 사용했던 색상들의 경우는 RGB 내부의 값이 0 또는 255여서 대응되는 16진수가 00 또는 FF임을 비교적 쉽게 짐작할 수 있었는데요. 예를 들어 RGB 값이 (173, 216, 230)인 경우 각 숫자에 대응되는 16진수를 머릿속으로 짐작하는 것은 쉽지 않습니다. 따라서 특정한 10진수에 대한 16진수를 얻는 방법을 사용해야 하는데요. 그 방법은 다음과 같습니다.

 

rgb = [173, 216, 230]
PRINT, rgb[2], FORMAT='(Z2.2)'
PRINT, rgb[1], FORMAT='(Z2.2)'
PRINT, rgb[0], FORMAT='(Z2.2)'

 

이와 같이 RGB를 구성하는 각 숫자에 대하여 포맷코드 Z를 적용하여 16진수로 나타낼 수 있습니다. 출력된 내용은 다음과 같습니다.

 

E6

D8

AD

 

결국 이러한 문자열들을 한데 모아주면 될 것입니다. 이를 위하여 다음과 같이 STRING, STRJOIN, REVERSE 등의 함수들을 활용합니다.

 

rgb_hex = STRJOIN(STRING(REVERSE(rgb), FORMAT='(Z2.2)'))
PRINT, rgb_hex

 

출력된 결과는 다음과 같습니다.

 

E6D8AD

 

그러면 이 내용을 바로 색상에 반영하면 됩니다. 앞선 예제에서 캡션 문자 표시 역할을 하는 XYOUTS 명령에서 이 값을 활용해봅시다.

 

XYOUTS, 60, 4, 'IDL', COLOR='E6D8AD'x, CHARSIZE=2, CHARTHICK=2, /DATA

 

표출 결과는 다음 그림과 같습니다.

 

 

그런데 여기서 혹시 rgb_hex 문자변수를 바로 COLOR 키워드에 부여해도 되지않을까 생각이 들 수도 있습니다. 즉 COLOR=rgb_hex와 같이 해도 되지않겠냐 하는 것인데요. 안됩니다. 문법상으로 '~~~~~~'x와 같은 형태로 적어줘야 하는데, '~~~~~~' 자체는 문자열이지만 여기에 x가 추가된 '~~~~~~'x는 그 자체가 문자열은 아니기 때문입니다. 따라서 위와 같이 rgb_hex를 얻고 출력해서 눈으로 확인한 다음에 이 값을 그대로 직접 적어주는 수밖에 없습니다. 하여간 이 방법을 사용하면 임의의 색상의 RGB 값에 대한 16진수 색상값을 얻고 활용할 수 있습니다.

 

그런데 여기서 조금만 더 나가본다면, DG 체계에서 색상을 RGB 값이 아닌 그냥 색상의 고유 이름으로 설정하고 싶다면 어떻게 하면 될까요? 즉 예를 들어서 orange 색상에 해당되는 16진수 색상값을 바로 사용하고자 할 경우입니다. 이 경우에는 !COLOR라는 시스템 변수를 사용하면 됩니다. 즉 다음과 같은 방식입니다.

 

rgb = !color.orange

rgb_hex = STRJOIN(STRING(REVERSE(rgb), FORMAT='(Z2.2)'))
PRINT, rgb_hex

 

이와 같이 !color 뒤에 .과 함께 색상이름을 적어주면 그 색상에 대한 RGB 값을 바로 얻을 수 있으며 나머지 과정은 그대로입니다. 이렇게 얻은 rgb_hex의 내용을 바로 활용하면 됩니다. 실제로 orange 색상에 대한 16진수 색상값은 00A5FF로 얻어집니다. 이 값을 그대로 이용해봅시다.

 

XYOUTS, 60, 4, 'IDL', COLOR='00A5FF'x, CHARSIZE=2, CHARTHICK=2, /DATA

 

표출 결과는 다음 그림과 같습니다.

 

 

따라서 DG 체계에서 몇몇 특정한 색상들만 표출에 활용해야 할 경우에는 이와 같은 방법을 사용하는 것도 고려해볼만 합니다. 다만 색상이 몇 개만 필요한 경우가 아니고 이미지의 표출과 같이 다수의 색상들로 디테일을 나타내는 작업을 할 경우에는 당연히 컬러테이블 기반의 작업이 필요할 것입니다. 따라서 상황에 따라 적절한 방식을 선택하여 사용하는 것이 중요함을 꼭 염두에 두시기 바랍니다.

반응형