Python / Pillow / RGB

3주차 2교시: RGB 색상과 도형 그리기

RGB 숫자를 색으로 번역하고, 좌표와 도형 명령이 한 장의 이미지가 되는 흐름을 배웁니다.

RGB 색상 조각과 좌표 기반 도형 구성을 보여 주는 3주차 2교시 이미지
색상 값과 좌표가 도형 명령으로 연결되는 과정

RGB 데이터와 도형 생성

핵심 개념
RGB, 색상 튜플, 도형
이전 학습
픽셀, 좌표, 유효 범위
도구
Pillow Image, ImageDraw
연결 실습
기하학적 이미지 제작

학습 목표

  1. RGB를 빨강, 초록, 파랑 빛의 세 채널로 설명
  2. 0부터 255까지의 세 정수로 색과 밝기 예측
  3. RGB 튜플의 변수 대입과 재사용 원리 설명
  4. Image.new()ImageDraw.Draw()의 역할 구분
  5. 사각형·타원·다각형의 좌표와 색상·윤곽선 인자 해석

학습 내용

이미지 좌표 복습

1교시에서는 픽셀 격자의 구조와 왼쪽 위 원점 (0, 0)을 기준으로 한 좌표를 학습했습니다. RGB 색상 값을 해석하기 전에 원점, 유효 범위와 이동 규칙을 확인합니다.

좌표가 같아도 색상 값에 따라 픽셀의 표현은 달라집니다. 예를 들어 (120, 80) 위치에 검정, 빨강, 흰색을 지정하면 서로 다른 결과가 나타납니다. 좌표는 위치를, RGB 값은 해당 위치의 색상을 나타냅니다.

1. 이미지 좌표에서 (0, 0)은 어디인가?

이미지의 왼쪽 위입니다. x는 오른쪽, y는 아래쪽으로 증가합니다.

2. 500 × 300 이미지의 오른쪽 아래 픽셀 좌표는?

(499, 299)입니다. 각 크기에서 1을 뺀 값이 마지막 픽셀 주소입니다.

3. (80, 120)에서 오른쪽으로 30, 위로 20 이동하면?

(110, 100)입니다. 오른쪽 이동은 x에 더하고, 위쪽 이동은 y에서 뺍니다.

좌표와 색상의 역할

1교시에서는 background_color(244, 239, 229)를 대입하고, 이 변수를 Image.new()의 세 번째 인자로 전달했습니다. 이번 교시에서는 튜플의 각 값이 의미하는 색상 채널을 해석합니다.

RGB 원리

세 색상 채널

RGB는 빨강(Red), 초록(Green), 파랑(Blue)의 세 성분으로 색을 표현하는 방식입니다. 각 성분을 채널이라고 합니다. Pillow의 RGB 모드에서는 각 채널을 0부터 255까지의 정수로 나타냅니다.

세 채널의 값은 독립적으로 조절할 수 있습니다. R만 변경하면 빨강 성분이, G만 변경하면 초록 성분이 달라집니다. 색상은 한 채널의 값만으로 결정되지 않으므로 세 값의 상대적인 크기와 차이를 함께 확인합니다.

각각의 밝기 조절 장치가 연결된 빨강, 초록, 파랑 조명이 같은 화면에 빛을 비추고, 세 빛이 겹치는 중심이 흰색으로 보이는 모습
세 채널의 독립 조절과 가산 혼합

세 조명의 밝기를 각각 조절하듯 RGB도 세 채널의 값을 따로 바꿉니다. 빛이 같은 위치에 더해지면 다른 색이 나타나며, 세 채널이 모두 최대인 (255, 255, 255)는 흰색입니다. 물감의 혼합이 아니라 빛의 합성을 설명하는 비유입니다.

8비트 채널과 값의 범위

Pillow의 일반적인 RGB 모드는 채널 하나를 8비트로 기록합니다. 8개의 이진 자리로 표현할 수 있는 경우는 2 ** 8 = 256가지이며, 0부터 시작하므로 값의 범위는 0~255가 됩니다. 세 채널이 각각 256가지 값을 가지므로 가능한 조합은 256 ** 3 = 16,777,216가지입니다.

RGB 가산 혼합 도식 검은 배경 위에서 빨강, 초록, 파랑 원이 겹치며 노랑, 청록, 자홍과 중앙의 흰색을 만드는 모습 R G B
화면의 RGB는 물감을 섞는 방식이 아니라 빛을 더하는 가산 혼합입니다. 세 채널이 모두 강하면 흰색에 가까워지고, 모두 0이면 검은색입니다.
대표 RGB 값과 예상 색상
RGB 값예상 색켜진 채널
(0, 0, 0)검정모두 꺼짐
(255, 255, 255)흰색세 채널 모두 최대
(255, 0, 0)빨강R만 최대
(0, 255, 0)초록G만 최대
(0, 0, 255)파랑B만 최대
(255, 255, 0)노랑R과 G가 최대
(0, 255, 255)청록G와 B가 최대
(255, 0, 255)자홍R과 B가 최대
(128, 128, 128)중간 회색세 채널의 밝기가 같음

가산 혼합과 물감 혼합의 차이

빨간 빛과 초록 빛을 강하게 더하면 노란 빛에 가까워집니다. 물감을 섞을 때의 경험과 결과가 다를 수 있으므로, 이번 수업에서는 빛의 세 채널 밝기로 판단합니다.

RGB 값의 해석

  1. 첫 번째는 R, 두 번째는 G, 세 번째는 B입니다.
  2. 가장 큰 값과 작은 값을 비교해 색상 계열을 예측합니다.
  3. 세 값이 같으면 검정부터 흰색까지의 무채색이 됩니다. 값의 차이가 생기면 색상 성분이 나타납니다.
RGB 값의 단계별 해석
채널 비교예상근거
(210, 70, 60)R이 가장 큼따뜻한 빨강 계열G와 B보다 R이 크게 우세함
(50, 120, 210)B가 가장 큼차가운 파랑 계열B가 우세하고 G가 일부 섞임
(220, 215, 205)세 값이 높고 가까움밝고 따뜻한 회백색전체 값이 높으며 R이 조금 더 큼
(35, 38, 42)세 값이 낮고 가까움어두운 청회색전체 값이 낮으며 B가 조금 더 큼

RGB 숫자는 색을 설명하는 정확한 데이터이지만, 숫자의 차이가 사람이 느끼는 밝기 차이와 언제나 같은 비율로 대응하는 것은 아닙니다. 또한 같은 값도 화면의 밝기와 색상 설정에 따라 조금 다르게 보일 수 있습니다. 이번 수업에서는 먼저 채널의 상대적 크기로 색의 방향을 예측하고 실제 결과를 확인하는 습관을 기릅니다.

단일 채널 변화 비교

색을 탐색할 때 세 값을 동시에 바꾸면 어떤 변화가 결과를 만들었는지 알기 어렵습니다. 먼저 기준색을 정하고 한 채널만 일정한 간격으로 바꾸면 숫자와 시각적 변화의 관계를 읽을 수 있습니다.

기준색 (220, 80, 60)에서 한 채널만 바꾸는 실험
변형RGB 값바꾼 값예상 관찰
기준(220, 80, 60)없음R이 강한 따뜻한 색
R 감소(160, 80, 60)R만 -60빨강의 우세가 줄어듦
G 증가(220, 140, 60)G만 +60노랑·주황 방향의 성격이 강해짐
B 증가(220, 80, 120)B만 +60세 채널 차이가 줄고 자홍 성분이 더해짐

채널 값을 비교해 색상의 변화를 예상한 뒤, 다음 단원의 배경색 변경 실습에서 실제 결과를 확인합니다.

개별 색상 분석 · 3분

색의 성격 예측

  1. (240, 40, 40)은 어느 채널이 가장 강한가?
  2. (40, 40, 240)과 비교하면 어느 쪽이 파랑에 가까운가?
  3. (40, 40, 40)(210, 210, 210) 중 어느 쪽이 더 밝은 회색인가?
  4. (255, 180, 0)에서 B 값을 높이면 색의 성격은 어느 쪽으로 이동할지 예상합니다.
색상 분석 답 확인

(240, 40, 40)은 R이 가장 강해 빨강 계열입니다. (40, 40, 240)은 B가 가장 강해 파랑에 가깝습니다. (210, 210, 210)이 더 밝은 회색입니다. 마지막 색에서 B를 높이면 빨강과 초록만 강한 주황·노랑 계열에 파랑 성분이 더해집니다. B가 R과 G에 가까워질수록 세 채널의 차이가 줄어 색은 더 중성적으로 보입니다. 정확한 인상은 실제 결과를 함께 확인합니다.

색상 데이터와 변수

코드 해석·실행·수정 절차

  1. 명령의 역할과 전달하는 인자를 구분해 코드를 해석합니다.
  2. 제공된 코드를 먼저 실행해 기준 결과를 확인합니다.
  3. 위치·크기·색상 가운데 한 속성씩 변경하고, 다시 실행한 결과와 비교합니다.

RGB 튜플과 변수

RGB 튜플은 빨강, 초록, 파랑 채널 값을 정해진 순서로 저장합니다. (235, 86, 75)에서 R은 235, G는 86, B는 75입니다.

코드에서는 세 정수를 쉼표로 구분한 튜플을 변수에 대입합니다. 각 값의 순서는 R, G, B이며, 위치를 바꾸면 다른 색상이 됩니다.

RGB 채널의 정수 자료형

(235, 86, 75)의 세 값은 계산 가능한 정수입니다. ("235", "86", "75")처럼 따옴표를 붙이면 세 값이 숫자가 아니라 문자열이 되므로 Pillow의 RGB 색상 값으로 올바르게 사용할 수 없습니다. 설명 글자에는 따옴표를 쓰고, 채널 숫자에는 쓰지 않습니다.

R is strongest
color_a = (230, 70, 50)

빨강 계열: R 값이 가장 큽니다.

B is strongest
color_b = (50, 70, 230)

파랑 계열: 같은 세 숫자의 순서만 바뀌었습니다.

색상 튜플을 변수에 대입하면 여러 도형에서 같은 값을 재사용할 수 있습니다. 반복되는 RGB 숫자 대신 변수를 참조하면 색상 정의를 한곳에 모아 관리할 수 있습니다. 변경된 색상을 이미지에 반영하려면 해당 변수를 사용하는 그리기 코드도 다시 실행해야 합니다.

paper = (244, 239, 229)
coral = (235, 86, 75)
blue = (48, 95, 180)
ink = (28, 31, 38)

배경색 변경과 결과 확인

1교시의 빈 이미지 생성 코드를 이용해 RGB 값과 화면의 색상을 연결합니다. 기존 노트북을 계속 사용하며, 새 노트북을 사용하는 경우에도 아래 코드를 한 셀에 입력하면 실행할 수 있습니다.

색상 적용

단일 채널과 배경색

from PIL import Image

background_color = (220, 80, 60)
image = Image.new("RGB", (400, 300), background_color)
image
  1. 코드를 실행해 R이 우세한 배경색을 확인합니다.
  2. background_color의 R 값만 220에서 160으로 변경합니다. G와 B 값은 유지합니다.
  3. 색상 변수의 대입과 이미지 생성을 포함한 셀 전체를 다시 실행해 배경색을 비교합니다.

변수의 숫자만 수정해도 이미 표시된 이미지가 바뀌는 것은 아닙니다. 수정한 값을 사용해 이미지를 다시 생성해야 결과에 반영됩니다.

이미지와 그리기 도구

배경색 변경에는 Image.new()만 사용했습니다. 이제 이미지의 일부 영역에 도형을 그리기 위해 ImageDraw를 추가합니다. 이미지를 생성하는 기능과 그 이미지의 픽셀을 수정하는 기능을 구분합니다.

from PIL import Image, ImageDraw는 이미지 모듈과 그리기 모듈을 불러옵니다. 1교시의 ImageImageDraw가 추가된 구문입니다.

from PIL import Image, ImageDraw

image와 draw의 역할

Image.new()는 지정한 크기와 배경색으로 이미지를 생성합니다. 이어서 ImageDraw.Draw(image)를 호출하면 그 이미지에 연결된 그리기 도구가 생성됩니다. 두 함수는 서로 다른 결과를 반환합니다.

두 대입문은 오른쪽 함수 호출 → 반환값 확인 → 왼쪽 변수에 대입의 순서로 처리됩니다. image는 이미지를, draw는 해당 이미지에 연결된 그리기 도구를 참조합니다.

왼쪽에는 빈 캔버스와 준비된 붓, 오른쪽에는 같은 캔버스에 붓으로 코랄색 사각형을 그린 상태를 나란히 비교한 모습
이미지와 그리기 도구의 역할

image는 색상 데이터가 남는 캔버스에, draw는 그 캔버스에 연결한 붓에 해당합니다. 도구를 준비하는 것만으로 그림이 생기지는 않습니다. draw.rectangle(...)을 실행하면 새 캔버스를 만드는 대신 연결된 이미지의 픽셀 값이 바뀝니다.

두 대입문을 오른쪽부터 읽는 순서
코드1. 오른쪽 실행2. 만들어지는 결과3. 왼쪽에 저장
image = Image.new(...)모드·크기·배경색으로 Image.new() 실행실제 픽셀을 가진 새 이미지생성한 이미지를 image로 참조
draw = ImageDraw.Draw(image)이미 만들어진 imageDraw()에 전달그 이미지에 도형을 그릴 수 있는 도구연결한 도구를 draw로 참조

ImageDraw 모듈과 draw 변수

ImageDraw는 Pillow의 모듈명이고, drawImageDraw.Draw(image)의 반환값을 참조하는 변수명입니다. 이름의 역할과 대소문자를 구분해야 합니다.

준비 코드는 이미지와 그리기 도구를 생성하지만, 도형을 그리거나 결과를 표시하지는 않습니다. 코드 실행과 화면 출력은 별개의 단계이므로 출력이 없다는 사실만으로 오류를 판단할 수 없습니다.

도형 실습부터는 600 × 400 캔버스를 사용합니다. 아래 준비 코드처럼 새 셀에서 Image.new()를 다시 실행하면 image는 새 이미지를 가리키고, 이전 셀의 출력은 그대로 남습니다.

from PIL import Image, ImageDraw

canvas_width = 600
canvas_height = 400
background_color = (244, 239, 229)

image = Image.new(
    "RGB",
    (canvas_width, canvas_height),
    background_color
)

draw = ImageDraw.Draw(image)

사각형의 생성과 수정

경계 상자

사각형과 타원은 네 숫자로 이루어진 경계 상자를 사용합니다. (left, top, right, bottom)왼쪽 경계의 x, 위쪽 경계의 y, 오른쪽 경계의 x, 아래쪽 경계의 y를 순서대로 기록합니다.

왼쪽 위와 오른쪽 아래 모서리가 표시된 정사각형, 가로로 긴 직사각형, 세로로 긴 직사각형 틀에 각각 꼭 맞는 원과 타원
두 모서리로 지정하는 도형의 범위

왼쪽 위와 오른쪽 아래 두 모서리로 도형이 들어갈 범위를 정합니다. 틀의 가로·세로 길이가 달라지면 그 안에 들어가는 도형의 비율도 달라집니다. 사각형과 타원은 모두 이런 경계 상자를 사용합니다. 나무 틀은 범위를 보여 주는 비유이며 실제 이미지에 자동으로 그려지는 테두리는 아닙니다.

(180, 120, 380, 320) 경계 상자 해석
의미화면에서의 위치
left = 180도형이 시작하는 왼쪽 x좌표원점에서 오른쪽으로 180픽셀
top = 120도형이 시작하는 위쪽 y좌표원점에서 아래로 120픽셀
right = 380도형이 끝나는 오른쪽 x좌표왼쪽보다 오른쪽에 있어야 함
bottom = 320도형이 끝나는 아래쪽 y좌표위쪽보다 아래에 있어야 함

경계 상자의 끝점 포함 규칙

Pillow의 ImageDraw.rectangle() 경계 상자는 시작점과 끝점을 모두 포함합니다. 따라서 (40, 40, 259, 179)는 정확히 가로 220 × 세로 140픽셀입니다. 이번 실습에서는 우선 네 숫자를 도형을 감싸는 왼쪽·위·오른쪽·아래 경계로 읽습니다.

draw.rectangle() 해석

draw.rectangle()는 그리기 도구 draw의 사각형 그리기 메서드를 호출합니다. 괄호 안에는 좌표와 색상을 인자로 전달합니다.

draw.rectangle((40, 40, 260, 180), fill=coral)
사각형 명령 한 줄의 기호별 의미
코드역할구문의 의미
draw앞에서 이미지와 연결한 그리기 도구이미지에 연결된 대상
.앞의 대상에서 뒤의 기능을 선택대상의 메서드 접근
rectangle사각형을 그리는 기능 이름사각형 그리기 메서드
( ... )기능 실행에 필요한 입력의 시작과 끝인자를 전달하는 호출 괄호
(40, 40, 260, 180)사각형이 들어갈 경계 상자왼쪽·위·오른쪽·아래 경계
fill=coral내부색 입력의 이름과 값내부색으로 coral 값 사용

이 명령은 (40, 40, 260, 180) 영역의 픽셀을 coral 값으로 채웁니다. 점 .은 대상의 속성이나 메서드에 접근하는 표기이며, rectangle()연결된 이미지를 직접 수정합니다. 수정된 결과는 image로 확인합니다.

대입과 키워드 인자의 구분

coral = (235, 86, 75)=은 값을 변수에 연결하는 대입 연산자입니다. 반면 함수 호출 내부의 fill=coral은 인자의 이름과 값을 함께 지정하는 키워드 인자입니다. coral의 값을 내부색 인자 fill에 전달하며, 별도의 fill 변수를 정의하지 않습니다.

사각형 생성 실습

먼저 제공된 좌표와 색상으로 사각형 하나를 생성합니다. 이 단계에서는 값을 변경하지 않고, 빈 이미지에 도형이 추가되는 결과를 확인합니다.

코드 실행

빈 이미지 위의 사각형

  1. 아래 코드를 한 줄씩 읽은 뒤 새 셀에 적고 실행합니다.
  2. 연한 배경의 왼쪽 위에 코랄색 사각형이 표시되는지 확인합니다.
from PIL import Image, ImageDraw

canvas_width = 600
canvas_height = 400
background_color = (244, 239, 229)
coral = (235, 86, 75)

image = Image.new(
    "RGB",
    (canvas_width, canvas_height),
    background_color
)
draw = ImageDraw.Draw(image)

draw.rectangle((40, 40, 260, 180), fill=coral)
image

이미지 재생성과 상태 변화

Image.new()를 다시 실행하면 같은 변수명 image에 새로운 빈 이미지가 대입됩니다. 이전 이미지에 그려 두었던 도형이 새 이미지로 자동 이동하지는 않습니다. 이어서 ImageDraw.Draw(image)도 다시 실행해 새 이미지에 그리기 도구를 연결해야 합니다.

처음 생성image = Image.new(...)
image → 빈 배경
도형 그리기draw.rectangle(...)
image → 배경 + 사각형
다시 생성image = Image.new(...)
image → 새로운 빈 배경

이 동작은 오류가 아니라 대입의 결과입니다. 2주차에 score = 10 다음 score = 20을 실행하면 새 값이 남았던 것과 같습니다. 이미지 역시 변수에 저장된 값이므로 새 이미지를 대입하면 현재 image가 가리키는 대상이 바뀝니다.

이미지 재생성과 실행 순서

좌표나 색상을 수정한 뒤에는 변수 대입 → 이미지 생성 → 그리기 도구 연결 → 도형 그리기 → 표시의 순서로 셀 전체를 다시 실행합니다. 이전 픽셀이 남지 않은 새 이미지에서 그려야 수정 결과를 정확히 비교할 수 있습니다. PNG 저장은 전체 구성을 완성한 뒤 다룹니다.

사각형의 좌표 수정

사각형의 크기를 유지하면서 이동하려면 왼쪽 위와 오른쪽 아래의 두 모서리에 같은 이동량을 적용합니다. 한쪽 모서리만 변경하면 위치뿐 아니라 크기도 달라집니다.

단일 속성 수정

사각형의 평행 이동

  1. 기준 사각형의 경계 상자 (40, 40, 260, 180)를 확인합니다.
  2. 왼쪽 위를 1교시의 예시 기준점 (150, 200)으로 이동하려면 x에 110, y에 160을 더합니다.
  3. 두 모서리에 같은 이동량을 적용해 전체 경계 상자를 (150, 200, 370, 340)으로 변경합니다.
  4. 앞의 사각형 생성 셀 전체를 다시 실행하고, 크기는 유지되며 위치만 바뀌었는지 확인합니다.

3교시에서는 1교시에서 개별 설계한 기준점 하나를 사각형의 왼쪽 위 기준점으로 사용합니다. 사각형 전체가 여백 안에 들어오도록 기준점을 조정한 뒤, 두 모서리를 함께 이동하는 원리를 적용합니다.

타원과 다각형

경계 상자와 타원의 비율

draw.ellipse()는 지정한 경계 상자에 맞는 타원을 그립니다. 사각형과 좌표 형식은 같지만, 영역 전체를 채우는 대신 타원 내부의 픽셀을 채웁니다. 예제의 blue는 앞에서 정의한 파란색 튜플입니다.

앞에서 살펴본 (180, 120, 380, 320) 경계 상자의 가로 차이는 380 - 180 = 200, 세로 차이는 320 - 120 = 200입니다. 가로와 세로가 같으므로 draw.ellipse()를 사용하면 원이 됩니다. 두 차이가 다르면 타원이 됩니다. 예를 들어 (180, 120, 480, 320)은 가로 차이 300, 세로 차이 200이므로 가로로 긴 타원을 만듭니다.

두 예제는 각각 빈 이미지에서 실행해 비교합니다. 앞의 이미지와 그리기 도구 준비 코드를 다시 실행한 뒤, 아래 명령 중 하나를 새 셀에 입력하고 마지막 줄에 image를 추가해 결과를 확인합니다.

Circle
draw.ellipse((180, 120, 380, 320), fill=blue)

가로 차이 200, 세로 차이 200으로 같은 비율입니다.

Ellipse
draw.ellipse((180, 120, 480, 320), fill=blue)

가로 차이 300, 세로 차이 200으로 가로가 더 깁니다.

다각형의 꼭짓점

draw.polygon()은 경계 상자 대신 여러 점의 좌표를 받습니다. 첫 점에서 둘째 점, 둘째 점에서 셋째 점으로 선을 잇고, 마지막 점에서 첫 점으로 돌아와 형태를 닫습니다. 삼각형에는 세 점, 사각형에는 네 점이 필요합니다.

먼저 다각형 내부에 사용할 노란색을 yellow에 대입합니다. 테두리에는 앞에서 정의한 짙은 색상 ink를 사용합니다.

yellow = (244, 190, 55)
triangle_points = (
    (420, 70),
    (560, 260),
    (350, 260)
)

draw.polygon(
    triangle_points,
    fill=yellow,
    outline=ink
)

코드를 실행하면 현재 이미지에 삼각형이 추가됩니다. 마지막 줄에 image를 추가해 내부 색상과 테두리를 확인합니다.

triangle_points의 겹친 괄호를 바깥부터 읽기
코드 범위묶는 대상의미
triangle_points = ...오른쪽 전체 값꼭짓점 튜플을 triangle_points에 대입
가장 바깥쪽 ( ... )꼭짓점 세 개삼각형을 만드는 전체 점 목록
(420, 70)첫 번째 점의 x와 y오른쪽 420, 아래 70 위치의 꼭짓점
(560, 260)두 번째 점의 x와 y오른쪽 아래 방향의 꼭짓점
(350, 260)세 번째 점의 x와 y왼쪽 아래 방향의 꼭짓점

안쪽 튜플은 한 꼭짓점의 x·y 좌표를 나타내고, 바깥쪽 튜플은 꼭짓점들을 순서대로 저장합니다. 이 구조를 통해 점의 좌표와 도형의 연결 순서를 함께 지정합니다.

단순 다각형의 꼭짓점은 윤곽을 따라 연결되는 순서로 작성합니다. 순서가 달라지면 선분이 교차해 의도와 다른 형태가 생길 수 있으므로, 코드 작성 전에 각 점과 연결 순서를 확인합니다.

선의 경로와 색상

draw.line(((40, 340), (560, 340)), fill=ink, width=6)(40, 340)에서 (560, 340)까지 가로선을 그립니다. 선은 내부 면적이 없으므로 fill이 선의 색을 뜻합니다. 3교시에는 이와 같은 기준선이 제공되며, 선의 좌표와 두께를 지정하는 코드는 유지합니다.

도형의 색상과 윤곽

fill도형 내부 색fill=coral

도형 안쪽 픽셀을 지정한 RGB 색상으로 채웁니다.

outline도형 테두리 색outline=ink

도형의 바깥 경계를 지정한 색으로 그립니다.

width테두리 두께width=4

테두리의 두께를 픽셀 단위 정수로 지정합니다.

xy도형의 위치와 범위(40, 40, 260, 180)

좌표 데이터로 도형이 차지할 영역을 정합니다.

세 도형의 결합

세 도형 명령에서 좌표를 읽는 방법
명령위치 데이터읽는 방법
rectangle(left, top, right, bottom)왼쪽 위와 오른쪽 아래 경계로 사각형 영역을 정함
ellipse(left, top, right, bottom)같은 경계 상자 안에 꼭 맞는 타원 또는 원을 그림
polygon((x1, y1), (x2, y2), ...)여러 꼭짓점을 작성한 순서대로 연결해 닫힌 도형을 그림

다음은 사각형·타원·다각형을 함께 그리는 코드입니다. 앞의 사각형 생성 셀에서 좌표를 기준값 (40, 40, 260, 180)으로 되돌린 뒤 셀 전체를 다시 실행하고, 새 셀에 아래 코드를 입력합니다. 같은 이미지 위에 세 도형이 순서대로 추가됩니다.

함수 인자와 쉼표

경계 상자 뒤, fill 뒤, outline 뒤의 쉼표는 각 입력을 분리합니다. 괄호 안에서 줄을 나누어 작성할 때에도 쉼표를 유지해야 합니다. 마지막 width=4 뒤의 쉼표는 생략할 수 있지만, 수업 코드에서는 다음 줄을 추가하기 쉽도록 남겨 둘 수 있습니다.

coral = (235, 86, 75)
blue = (48, 95, 180)
yellow = (244, 190, 55)
ink = (28, 31, 38)

draw.rectangle(
    (40, 40, 260, 180),
    fill=coral,
    outline=ink,
    width=4
)

draw.ellipse(
    (180, 120, 380, 320),
    fill=blue
)

draw.polygon(
    ((420, 70), (560, 260), (350, 260)),
    fill=yellow
)

도형 명령만으로는 새 출력이 표시되지 않습니다. 위 코드의 마지막에 image를 별도의 줄로 추가하고 셀을 실행해 현재 결과를 확인합니다. 이미 표시된 이전 셀의 이미지는 자동으로 갱신되지 않습니다.

그리기 순서

현재 수업의 불투명 RGB 도형은 기존 픽셀 위에 새 색상 값을 기록합니다. 두 도형이 겹치면 코드에서 나중에 실행한 도형이 겹친 부분에서 앞 도형을 가립니다.

이 방식은 종이에 물감을 올리는 순서와 비슷해 페인터스 알고리즘이라고 설명할 수 있습니다. 먼저 그린 형태는 아래에 놓이고, 나중에 그린 형태는 그 위에 놓입니다. 별도의 레이어 패널이 없어도 코드의 실행 순서가 시각적 앞뒤 관계를 만듭니다.

위쪽은 코랄 사각형 다음 파란 원을 그려 겹친 부분이 파란색이고, 아래쪽은 파란 원 다음 코랄 사각형을 그려 같은 겹친 부분이 코랄색인 두 순서
실행 순서와 겹침 결과

각 줄을 왼쪽에서 오른쪽으로 읽습니다. 위쪽은 원을 나중에, 아래쪽은 사각형을 나중에 그렸습니다. 같은 위치와 색상이라도 순서가 바뀌면 겹친 부분의 색이 달라집니다. 불투명 RGB 이미지에서는 물감처럼 색을 섞거나 도형을 별도 레이어로 보관하는 것이 아니라, 해당 픽셀을 나중에 지정한 색으로 덮어씁니다.

Order A
draw.rectangle((40, 40, 260, 180), fill=coral)
draw.ellipse((180, 120, 380, 320), fill=blue)

겹친 부분에서는 나중에 그린 파란 타원이 보입니다.

Order B
draw.ellipse((180, 120, 380, 320), fill=blue)
draw.rectangle((40, 40, 260, 180), fill=coral)

좌표가 같아도 겹친 부분에서는 나중에 그린 코랄 사각형이 보입니다.

개별 실행 추적 · 2분

두 줄의 순서 교체

색상과 좌표는 그대로 두고 파란 원이 코랄 사각형 뒤로 가게 하려면 어느 두 줄의 순서를 바꾸어야 하는지 적습니다. 코드는 위에서 아래로 실행된다는 2주차 원리를 사용합니다.

그리기 순서 답 확인

파란 원을 먼저 그리고 코랄 사각형을 나중에 그립니다. Pillow에서 별도의 레이어 패널을 조작하는 것이 아니라, 코드 줄의 실행 순서가 앞뒤 관계를 만듭니다.

화면 구성과 팔레트

팔레트의 역할

팔레트는 화면에 사용할 색상의 집합입니다. 이 실습에서는 색상을 배경색, 주조색, 보조색, 강조색, 윤곽색으로 구분합니다. 각 역할에 변수를 연결하면 색상이 달라져도 화면의 구성 체계를 유지할 수 있습니다.

기하학적 이미지에서 사용할 다섯 가지 색상 역할
역할변수 예사용 원칙확인할 질문
배경색background_color가장 넓은 면적을 차지하며 다른 색의 기준이 됨주요 도형이 배경과 구분되는가?
주조색primary_color큰 형태 또는 중심 형태에 사용화면의 첫인상을 형성하는가?
보조색secondary_color주조색과 차이를 만들되 경쟁하지 않게 사용주요 형태와 관계가 읽히는가?
강조색accent_color작은 면적에 제한적으로 사용해 시선을 모음어디를 먼저 보아야 하는지 분명한가?
윤곽색outline_color배경과 도형 모두에서 경계가 보이도록 선택얇은 선도 충분히 구분되는가?
background_color = (244, 239, 229)
primary_color = (235, 86, 75)
secondary_color = (48, 95, 180)
accent_color = (244, 190, 55)
outline_color = (28, 31, 38)

coral이나 blue처럼 색 자체를 이름으로 사용할 수도 있지만, primary_coloraccent_color처럼 역할로 이름을 정하면 팔레트 전체를 다른 색조로 바꾸기 쉽습니다. 강조색을 노랑에서 연두로 바꾸어도 도형 코드에서는 계속 accent_color라는 같은 의미를 유지할 수 있습니다.

색상·명암·형태의 구분

서로 다른 RGB 값을 사용해도 두 색의 밝기가 비슷하면 경계가 약하게 보일 수 있습니다. 특히 작은 글자나 얇은 선은 배경과 충분한 명암 차이가 필요합니다. 이번 기하학 이미지에서는 색뿐 아니라 크기, 위치, 윤곽선도 함께 사용해 형태를 구분합니다.

모든 도형을 임의의 순서로 나열하기보다 화면의 구조에 따라 순서를 정하면 코드를 읽기 쉽습니다. 일반적인 출발 순서는 배경 → 큰 면 → 보조 형태 → 작은 강조 → 윤곽과 선입니다. 반드시 지켜야 하는 규칙은 아니지만, 나중에 무엇이 무엇을 가리는지 예측하기 쉬운 기준이 됩니다.

기하학적 이미지의 권장 그리기 순서
순서요소역할코드 예
1배경전체 화면의 기본 톤Image.new(..., background_color)
2큰 사각형화면의 주요 무게와 방향 설정draw.rectangle(...)
3원 또는 타원직선 구조와 대비되는 곡선 추가draw.ellipse(...)
4작은 다각형시선을 모으는 강조점 생성draw.polygon(...)
5선과 윤곽정렬 기준이나 경계 강조draw.line(...)

형태가 앞에 있다는 사실과 시선이 먼저 간다는 사실은 완전히 같지 않습니다. 작은 노란 삼각형은 가장 나중에 그려져 앞에 놓이더라도, 면적이 큰 파란 원보다 반드시 강하게 보인다고 단정할 수 없습니다. 색 대비, 크기, 위치, 주변 여백이 함께 시각적 위계를 만듭니다. 코드는 순서를 정하고, 최종 위계는 결과를 보며 조정합니다.

전체 코드와 실행 결과

아래 코드는 기하학적 이미지 제작의 기준 예제입니다. 크기와 팔레트 설정 → 이미지 생성 → 도형 배치 → 결과 확인 → 파일 저장의 흐름을 확인합니다. 먼저 제공된 값 그대로 실행해 예상 이미지와 PNG 파일이 만들어지는지 확인하고, 그 뒤에 수정할 속성을 구분합니다. 기준 결과가 있어야 입력 오류와 구성 변경의 영향을 구분할 수 있습니다.

좌표 설계에서 도형 수정으로의 연결
학습 내용확인 사항3교시 적용
기준점 설계기준점 하나의 좌표와 배치 의도그 점을 사각형의 왼쪽 위 기준점으로 사용
경계 상자와 이동왼쪽 위·오른쪽 아래 좌표의 관계가로·세로 크기를 유지한 사각형의 위치 변경
안전 영역과 여백기준점뿐 아니라 도형 전체의 범위여백 확보를 위한 기준점 조정과 이유 기록

전체 코드의 단계별 구성

전체 코드는 주석으로 구분한 일곱 개의 작업 단계로 구성됩니다. 각 단계에서 생성하거나 수정하는 값과 이미지를 확인하면서 위에서 아래로 실행 순서를 추적합니다.

코드 블록의 구분과 실행 순서
표기Python의 처리학생이 활용하는 방법
# 설명# 뒤부터 줄 끝까지 실행하지 않음다음 코드 묶음의 목적을 먼저 읽음
빈 줄실행 결과에 영향을 주지 않음준비·도형·출력 같은 단계의 경계로 봄
괄호 안의 들여쓰기괄호가 닫힐 때까지 같은 명령의 입력으로 처리좌표·색상·두께를 한 줄씩 구분해 읽음
위에서 아래의 줄 순서앞에서 만든 값과 상태를 다음 줄이 사용도구 → 이미지 → 도형 → 출력 순서를 유지
from PIL import Image, ImageDraw

# 1. 크기와 팔레트
canvas_width = 600
canvas_height = 400
background_color = (244, 239, 229)
primary_color = (235, 86, 75)
secondary_color = (48, 95, 180)
accent_color = (244, 190, 55)
outline_color = (28, 31, 38)

# 2. 빈 이미지와 그리기 도구
image = Image.new(
    "RGB",
    (canvas_width, canvas_height),
    background_color
)
draw = ImageDraw.Draw(image)

# 3. 큰 사각형으로 기본 구조 만들기
draw.rectangle(
    (50, 60, 330, 240),
    fill=primary_color,
    outline=outline_color,
    width=4
)

# 4. 곡선 형태를 겹쳐 대비 만들기
draw.ellipse(
    (230, 100, 510, 360),
    fill=secondary_color,
    outline=outline_color,
    width=4
)

# 5. 작은 삼각형으로 강조점 만들기
triangle_points = (
    (390, 55),
    (560, 220),
    (340, 220)
)
draw.polygon(
    triangle_points,
    fill=accent_color,
    outline=outline_color,
    width=4
)

# 6. 아래쪽 기준선 추가하기
draw.line(
    ((40, 340), (560, 340)),
    fill=outline_color,
    width=6
)

# 7. 결과 확인과 PNG 파일 저장
display(image)
image.save("week03_학번_이름.png")

실행 상태 추적

각 코드 묶음 실행 직후의 상태
단계컴퓨터 내부에서 달라진 것Colab 화면에서 즉시 보이는 것
1. 도구 가져오기ImageImageDraw 이름을 사용할 수 있게 됨정상이라면 별도 출력 없음
2. 크기와 팔레트일곱 개 변수에 숫자와 RGB 튜플이 저장됨별도 출력 없음
3. 이미지 생성600 × 400 배경 이미지가 image에 저장됨아직 display() 전이므로 보이지 않음
4. 도형 그리기사각형·타원·삼각형·선이 같은 image의 픽셀을 차례로 수정각 명령마다 자동 미리보기되지 않음
5. display(image)현재 이미지 상태는 그대로 유지완성된 이미지가 셀 아래에 표시됨
6. image.save(...)현재 이미지가 PNG 파일로 기록됨파일 목록에서 파일명을 확인할 수 있음
Pillow 기준 코드의 기하학적 이미지 구성 미리보기 따뜻한 흰색 배경 위에 코랄 사각형, 파란 타원, 노란 삼각형과 어두운 가로선이 겹쳐진 구성
기준 코드의 구성 미리보기입니다. 실제 실습에서는 좌표와 팔레트를 바꾸어 형태의 비율, 겹침, 시각적 무게를 조정합니다.

미리보기와 저장

display(image)는 현재 런타임 메모리에 있는 이미지를 노트북 화면에 보여줍니다. 이 출력만으로는 제출할 PNG 파일이 만들어지지 않습니다. image.save("week03_학번_이름.png")를 실행해야 현재 이미지가 파일로 기록됩니다.

Pillow의 save()는 별도의 형식을 지정하지 않으면 파일명의 확장자를 보고 저장 형식을 결정합니다. 이번 주에는 면 색과 윤곽선이 분명한 기하학 이미지이므로 .png를 사용합니다. 파일명을 .jpg로 바꾸는 것은 단순히 글자만 바꾸는 일이 아니라 다른 저장 형식을 선택하는 일입니다.

이미지 표시와 파일 저장 구문의 구성
코드역할구문의 의미
displayColab 출력 영역에 이미지 등을 표시하는 기능출력 영역에 결과 표시
(image)보여 줄 대상을 괄호 안에 전달출력 대상 이미지
image.저장 기능을 사용할 대상저장할 이미지 객체
save이미지 파일을 기록하는 기능이미지 저장 메서드
("week03_학번_이름.png")파일명을 문자열 입력으로 전달저장 파일명 지정
.png파일 형식을 나타내는 확장자PNG 저장 형식 지정

파일명 구분과 결과 보관

수정 전후를 비교하려면 result_a.png, result_b.png처럼 파일명을 구분합니다. 같은 경로에 같은 파일명으로 저장하면 기존 파일을 덮어씁니다. Colab 런타임의 파일은 영구 보관되지 않으므로 완성한 PNG를 자신의 컴퓨터에 다운로드합니다.

코드 수정 범위

2교시의 기준 코드에서는 색상·좌표·두께·파일명을 수정 대상으로 구분합니다. 라이브러리와 메서드의 이름, 괄호·쉼표 등의 구문은 유지합니다. 수정 대상과 문법 요소를 구분하면 의도한 변화의 원인을 추적하기 쉽습니다.

기준 코드에서 안전하게 수정할 범위
구분코드 예이번 실습의 행동이유
수정(235, 86, 75)0~255 안에서 채널 값 하나 변경도형의 색을 조절하는 데이터
수정(50, 60, 330, 240)위치 변경은 두 모서리를 같은 거리만큼 이동, 크기 변경은 경계 간격 조정위치와 크기의 변화를 구분하기 위한 좌표 데이터
수정width=44를 2 또는 8처럼 양의 정수로 변경윤곽선 두께를 조절하는 데이터
수정"week03_학번_이름.png"따옴표와 .png는 남기고 학번·이름 교체제출 파일을 식별하기 위한 문자열
유지from, import, PIL철자와 대소문자를 그대로 유지Python과 라이브러리가 정한 이름
유지Image.new, draw.rectangle기능 이름과 점을 그대로 유지실행할 기능을 찾는 경로
유지괄호, 쉼표, 따옴표여는 기호·닫는 기호와 입력 구분을 유지코드 구조를 Python에 전달하는 문법
RGB 단일 채널 수정 · 2분

빨강 채널 변화와 결과 예측

primary_color = (235, 86, 75)에서 첫 값 235만 175로 바꿉니다. 실행하기 전에 어느 도형이 바뀌는지, R의 우세가 강해질지 약해질지 적습니다. 그다음 변수 대입부터 이미지 생성과 도형 그리기를 다시 실행해 실제 결과를 비교합니다.

빨강 채널 수정 결과

primary_color를 사용하는 큰 사각형의 색이 바뀝니다. R은 235에서 175로 줄고 G와 B는 그대로이므로 빨강 채널의 우세가 약해집니다. 타원·삼각형·윤곽선은 다른 색상 변수를 사용하므로 값이 바뀌지 않습니다.

수정 지점과 변화

아래는 2교시 기준 코드의 속성을 비교하기 위한 실험 예시입니다. 캔버스 크기를 변경하면 기존 도형이 새 이미지 범위를 벗어날 수 있으므로 좌표 범위도 함께 확인합니다. 3교시 제출 실습의 수정 범위는 별도로 지정됩니다.

기준 코드의 수정 지점과 예상 변화
수정 지점바뀌는 결과먼저 시도할 변화
canvas_width, canvas_height전체 이미지의 비율과 사용 가능한 영역600 × 400을 500 × 500으로 변경
다섯 색상 변수배경과 형태의 전체 인상한 변수의 채널 하나만 ±30 변경
사각형 경계 상자큰 면의 위치, 가로·세로 비율오른쪽 경계만 40 증가
타원 경계 상자원의 크기 또는 타원의 방향아래쪽 경계를 40 감소
triangle_points강조점의 방향과 실루엣첫 꼭짓점의 x만 30 이동
도형 코드의 순서겹친 부분의 앞뒤 관계삼각형을 타원보다 먼저 그리기

수정 전 결과를 저장하고 위치·크기·색상 가운데 한 속성씩 변경합니다. 여기서 하나는 숫자의 개수가 아니라 비교할 시각적 속성을 뜻합니다. 사각형의 위치만 바꾸려면 두 모서리의 좌표를 함께 수정해야 하며, 크기와 색상은 유지합니다. 앞의 RGB 연습은 색상 변화 중에서도 한 채널의 영향만 분리해 확인하는 예입니다.

코드 수정과 재실행 절차

  1. 먼저 제공된 전체 코드를 위에서 아래로 실행해 기준 결과를 확인합니다.
  2. 변경할 속성을 하나 정하고, 그 속성을 조절하는 값들을 수정합니다. 비교 대상이 아닌 속성은 유지합니다.
  3. 변수 대입과 이미지 생성부터 모든 도형, 표시, 저장을 순서대로 다시 실행합니다.
  4. 의도한 변화가 맞는지 이미지로 확인한 뒤 저장합니다.

전체 실행 순서는 변수 대입 → 이미지 생성 → 그리기 도구 연결 → 도형 그리기 → 표시 → 저장입니다.

팔레트 비교

같은 형태에 두 팔레트를 적용합니다. 도형의 좌표와 실행 순서는 그대로 두고 색상 변수만 바꾸면, 형태 변화와 색상 변화의 영향을 분리해서 관찰할 수 있습니다. 위치·크기·색상을 한꺼번에 수정하면 각 속성의 영향을 구분하기 어렵지만, 기하 구조를 고정하면 두 이미지의 차이가 팔레트에서 비롯되었다고 설명할 수 있습니다. 이것이 프로그래밍에서 변인을 통제하며 비교하는 기본 태도입니다.

팔레트 예측

각 RGB 튜플의 채널 값을 비교해 배경의 밝기, 도형의 색상 계열과 윤곽의 대비를 예상합니다. 색 이름을 특정하기보다 수치와 시각적 특성의 관계에 근거해 기록합니다.

Palette A / light
background_color = (244, 239, 229)
primary_color = (235, 86, 75)
secondary_color = (48, 95, 180)
accent_color = (244, 190, 55)
outline_color = (28, 31, 38)

밝은 배경, R이 강한 주조색, B가 강한 보조색, R과 G가 강한 강조색의 관계를 관찰합니다.

Palette B / dark
background_color = (24, 31, 44)
primary_color = (79, 130, 190)
secondary_color = (205, 92, 122)
accent_color = (238, 210, 120)
outline_color = (236, 239, 244)

낮은 값의 배경, B가 강한 주조색, R이 강한 보조색, 세 값이 높은 윤곽색의 관계를 관찰합니다.

개별 예측 · 2분

팔레트의 사전 분석

  1. 어느 팔레트의 배경이 더 어두운가?
  2. 각 팔레트에서 사각형과 타원은 따뜻한 색과 차가운 색 가운데 어느 쪽에 가까운가?
  3. 어두운 배경에서 형태의 경계를 보이게 하는 값은 무엇인가?
실행 전 예측의 기준 답안

팔레트 B의 배경은 세 값이 모두 낮으므로 더 어둡습니다. 팔레트 A의 사각형은 R이 강해 따뜻하고 타원은 B가 강해 차갑습니다. 팔레트 B에서는 이 역할이 서로 바뀝니다. 어두운 배경에서는 세 값이 모두 높은 outline_color = (236, 239, 244)가 밝은 경계를 만듭니다.

팔레트 실행

  1. 전체 기준 코드에 팔레트 A를 넣고 위에서 아래로 실행합니다.
  2. 마지막 저장 이름을 week03_학번_이름_palette_a.png로 바꾸어 저장합니다.
  3. 다섯 색상 변수의 값만 팔레트 B로 교체합니다. 좌표와 도형 순서는 수정하지 않습니다.
  4. 변경한 색상 변수의 대입부터 이미지 생성, 도형 그리기, 표시를 다시 실행한 뒤 week03_학번_이름_palette_b.png로 저장합니다.
같은 기하학적 구성에 적용한 밝은 팔레트와 어두운 팔레트 왼쪽에는 밝은 바탕의 코랄 사각형, 파란 타원, 노란 삼각형이 있고 오른쪽에는 같은 위치에 어두운 바탕의 파란 사각형, 붉은 타원, 연노란 삼각형이 있다 PALETTE A PALETTE B
좌표와 도형 순서는 같지만 색상 역할의 값이 달라지면 배경과 형태의 분리, 화면의 온도감, 강조점의 인상이 달라집니다.

비교와 기록

두 결과를 비교하는 기록표
비교 기준팔레트 A팔레트 BRGB 근거
배경과 도형의 분리밝은 배경과 어두운 윤곽의 대비어두운 배경과 밝은 윤곽의 대비배경과 윤곽의 세 채널 값 차이
따뜻한 형태와 차가운 형태사각형이 따뜻하고 타원이 차가움사각형이 차갑고 타원이 따뜻함R 또는 B 가운데 우세한 채널
작은 강조점노란 삼각형연노란 삼각형R과 G가 높고 주변 색과 차이가 남
전체 인상밝고 선명한 낮의 구성어둡고 빛나는 야간의 구성배경의 전체 밝기와 윤곽 대비

비교 기록에는 시각적 인상과 그 근거를 함께 작성합니다. 예를 들어 팔레트 B의 경계가 더 뚜렷하다고 판단했다면 어두운 배경과 밝은 윤곽색의 대비를 근거로 제시할 수 있습니다. 표의 설명은 유일한 정답이 아니라 관찰 결과를 RGB 데이터와 연결하는 예시입니다.

확장 정리 문장 · 1분

팔레트 비교 결과 정리

“도형의 좌표를 바꾸지 않고 색상 변수만 바꾸었을 때, ________은 그대로이고 ________은 달라졌다. 그 근거는 ________이다.”

정리 문장 예시

도형의 좌표를 바꾸지 않고 색상 변수만 바꾸었을 때, 형태의 위치와 겹침은 그대로이고 화면의 밝기와 온도감은 달라졌습니다. 그 근거는 팔레트 B의 배경 RGB 값이 모두 낮고 사각형과 타원에서 우세한 채널이 서로 바뀌었다는 점입니다.

보충 설명

기본 도형 생성과 저장을 마친 뒤 필요한 항목을 선택해 확인합니다. 튜플의 인덱스 접근, 모듈 이름의 구분과 오류 메시지 해석을 위한 참고 자료입니다.

튜플의 기호와 인덱스

RGB 튜플은 쉼표로 구분한 세 값을 둥근괄호 안에 작성합니다. 개별 채널을 참조할 때에는 변수명 뒤의 대괄호에 인덱스를 작성합니다. 튜플 구성요소 참조에 사용하는 표기를 구분해야 합니다.

coral = (235, 86, 75)와 확인 코드의 기호
기호 또는 코드이름이번 코드에서 하는 일해석
(235, 86, 75)튜플 표기R·G·B 세 값을 하나의 튜플로 묶음세 정수의 순서 있는 묶음
,쉼표첫째·둘째·셋째 값의 경계를 구분튜플 요소의 구분
coral[0]인덱스 접근0번 위치, 즉 첫 번째 R 값을 확인첫 번째 채널 R의 값
type(coral)자료형 확인coral에 저장된 값의 종류를 확인변수에 연결된 값의 자료형 확인
"R:"문자열출력 결과 앞에 설명 글자를 표시출력 항목을 식별하는 문자열

튜플의 개별 값은 인덱스로 참조합니다. 인덱스는 0부터 시작하는 위치 번호입니다. 아래 코드의 coral[0], coral[1], coral[2]는 각각 R, G, B 값을 반환합니다.

채널 값 확인

1교시 노트북에 새 코드 셀을 추가해 채널 값 확인 코드를 실행합니다. 이 보충 실습은 RGB 튜플의 각 값을 인덱스로 참조하는 방법을 확인하는 용도입니다.

코드 실행

coral의 세 채널 값

  1. 각 줄의 역할을 확인한 뒤 아래 코드를 셀에 입력합니다.
  2. Shift+Enter로 실행합니다.
  3. 출력에서 tuple, 235, 86, 75를 찾습니다.
coral = (235, 86, 75)

print(type(coral))
print("R:", coral[0])
print("G:", coral[1])
print("B:", coral[2])

<class 'tuple'>
R: 235
G: 86
B: 75

이번 주의 튜플 사용 범위

튜플의 추가 연산이나 자료구조 일반 이론은 다루지 않습니다. (width, height)는 크기 두 값, (x, y)는 위치 두 값, (R, G, B)는 색상 세 값을 정해진 순서로 묶는 표기로 사용합니다.

라이브러리와 import

Pillow는 이미지의 생성·편집·저장을 지원하는 Python 라이브러리입니다. 이번 실습은 모듈 불러오기, 이미지 생성, 도형 그리기, 결과 표시와 저장의 순서로 구성됩니다.

모듈 불러오기 구문의 구성 요소
코드역할구문의 의미
from도구를 찾을 위치를 알리는 Python의 예약어대상 패키지 지정
PILPillow 기능을 불러올 때 사용하는 패키지 이름Pillow의 패키지명
import뒤의 이름을 현재 코드에서 사용하도록 가져오는 예약어모듈 이름 불러오기
Image이미지를 만들고 저장하는 기능이미지 생성·편집 모듈
,가져올 이름 두 개를 구분모듈 이름의 구분
ImageDraw이미지 위에 도형을 그리는 기능도형 그리기 모듈

이 구문은 PIL 패키지의 ImageImageDraw 모듈을 현재 코드에서 사용할 수 있도록 불러옵니다. fromimport는 Python 예약어이며, 패키지명과 모듈명은 정해진 철자와 대소문자를 유지해야 합니다.

Pillow와 PIL의 명칭 구분

라이브러리의 현재 배포 이름은 Pillow이지만, Python 코드에서는 기존 호환 이름인 PIL을 사용해 가져옵니다. 따라서 from Pillow import Image로 바꾸지 않습니다. 대문자와 소문자도 서로 다른 이름으로 처리되므로 제공된 철자를 그대로 사용합니다.

Pillow 코드에서 만나는 네 이름의 역할
이름종류이번 수업에서 하는 일
PIL패키지 이름설치한 Pillow 기능을 Python 코드로 불러올 때 사용하는 이름
Image이미지 기능빈 이미지를 만들고 결과를 저장
ImageDraw그리기 기능이미지 위에 선과 도형을 기록
image, draw사용자 정의 변수현재 이미지와 그리기 도구를 참조
전체 실행 과정 요약
01 / Import모듈 불러오기

ImageImageDraw 모듈을 불러옵니다.

02 / Canvas이미지 생성

1교시와 같은 Image.new()로 600 × 400 캔버스를 만듭니다.

03 / Draw그리기 도구 연결

생성된 이미지에 도구를 연결하고 도형을 그립니다.

04 / Output표시와 저장

결과를 확인한 뒤 PNG 파일로 남깁니다.

각 단계는 앞 단계의 결과를 사용합니다. 셀을 아래에서부터 실행하면 아직 만들어지지 않은 imagedraw 때문에 오류가 날 수 있습니다.
1from PIL import Image, ImageDrawPillow에서 이미지 생성 기능과 그리기 기능을 현재 노트북으로 가져옵니다.
2image = Image.new(...)모드, 크기, 배경색을 사용해 실제 픽셀 데이터를 만들고 image에 저장합니다.
3draw = ImageDraw.Draw(image)도형 명령이 어느 이미지를 수정할지 연결하고 그 도구를 draw에 저장합니다.
4draw.rectangle(...)연결된 이미지의 해당 좌표 픽셀을 사각형의 색상으로 바꿉니다.
5display(image)현재 픽셀 상태를 Colab 출력 영역에 보여줍니다.
6image.save(...)현재 픽셀 상태를 지정한 이름의 파일로 기록합니다.
코드의 실행에 따라 이미지 상태가 순차적으로 갱신됩니다. 이미지가 먼저 존재해야 그리기 도구를 연결할 수 있고, 도형을 그린 뒤에 표시하고 저장해야 최종 결과가 반영됩니다.

주요 오류와 점검 항목

3교시 전에 구분할 대표 문제
보이는 문제가능한 원인먼저 확인할 것
SyntaxError괄호·따옴표가 닫히지 않았거나 입력 사이의 쉼표가 빠짐가장 최근에 수정한 줄의 여닫는 기호와 쉼표 확인
NameError: image이미지 생성 셀을 아직 실행하지 않음위쪽 셀부터 순서대로 실행했는지 확인
NameError: drawImageDraw.Draw(image) 셀을 실행하지 않음그리기 도구의 생성 여부와 변수명 draw의 철자 확인
오류 메시지 없이 출력이 없음변수와 도형 코드까지만 실행하고 display(image)를 실행하지 않음셀 마지막까지 실행되었는지 확인
도형이 보이지 않음좌표가 이미지 경계 밖에 있거나 다른 도형에 가림좌표 범위와 도형 코드의 실행 순서 확인
수정한 색이나 좌표가 반영되지 않음변수만 바꾸고 이미지 생성과 도형 명령을 다시 실행하지 않음변수 대입부터 이미지 생성·그리기·표시를 순서대로 재실행
예상과 다른 색RGB 순서가 바뀌었거나 팔레트 변수를 잘못 사용R, G, B 순서와 각 값의 0~255 범위 확인
PNG 파일이 없음미리보기만 하고 save()를 실행하지 않음저장 셀 실행 여부와 파일명 확장자 확인

오류 확인 순서

오류 메시지의 마지막 줄에서 종류를 확인한 뒤, 발생 위치와 선행 코드의 실행 여부를 점검합니다.

  1. 오류 메시지의 마지막 줄에 표시된 이름과 설명을 확인합니다.
  2. SyntaxError는 문법 요소, NameError는 이름의 철자와 정의 여부를 먼저 점검합니다.
  3. 오류가 발생한 줄과 최근 수정한 부분을 기준 코드와 비교합니다.
  4. 필요한 모듈과 변수를 먼저 준비한 뒤 이미지 생성부터 순서대로 다시 실행합니다.
Message
NameError: name 'draw' is not defined

Python이 현재 실행 공간에서 draw이라는 이름을 찾지 못했다는 뜻입니다.

Check
draw = ImageDraw.Draw(image)

이 줄을 실행했는지, draw의 철자와 대소문자가 아래 도형 코드와 같은지 확인합니다.

학습 내용 점검

핵심 개념 점검

  • RGB 튜플의 R·G·B 순서 해석
  • 이미지 크기·좌표·색상에 해당하는 변수 구분
  • imagedraw의 역할 구분
  • 도형 좌표와 fill·outline·width 인자 해석
  • 실행 순서에 따른 겹침 결과 예측
  • 미리보기와 PNG 파일 저장의 구분
개별 학습 점검 · 3분

도형 명령의 구성 요소

다음 명령을 좌표, 내부 색, 테두리 색, 두께라는 네 요소로 나누어 자신의 말로 설명합니다.

draw.rectangle(
    (60, 80, 260, 220),
    fill=(240, 90, 70),
    outline=(30, 30, 35),
    width=5
)
한 줄 설명의 기준 답안

왼쪽 60, 위 80, 오른쪽 260, 아래 220의 경계 상자에 사각형을 그립니다. 내부는 R이 강한 (240, 90, 70) 색으로 채우고, 테두리는 어두운 회색 (30, 30, 35)로 5픽셀 두께로 그립니다.

수업 후 개별 복습

1. (255, 0, 255)는 어떤 두 채널이 켜진 색인가?

R과 B 채널이 최대이고 G는 꺼져 있습니다. 빨강과 파랑 빛이 섞인 자홍 계열입니다.

2. Image.new()와 ImageDraw.Draw()의 역할 차이는?

Image.new()는 모드, 크기, 배경색으로 이미지 데이터를 만들고, ImageDraw.Draw(image)는 그 이미지에 도형을 그릴 수 있는 도구를 연결합니다.

3. ellipse에 전달한 네 좌표는 원의 중심과 반지름인가?

아닙니다. 이번 수업의 draw.ellipse()에는 타원을 감싸는 경계 상자의 왼쪽, 위, 오른쪽, 아래 좌표를 전달합니다.

4. display(image)까지 실행했는데 파일이 생기지 않은 이유는?

display(image)는 현재 결과를 노트북에 보여줄 뿐입니다. 파일로 남기려면 image.save("파일명.png")를 별도로 실행해야 합니다.

학습 범위

이번 실습의 범위는 불투명 RGB 이미지의 색상 지정, 도형 생성과 PNG 저장입니다. 투명도, 그라디언트, 반복 패턴과 안티앨리어싱은 후속 학습 주제입니다.

3교시 실습 개요

3교시에서는 제공된 600 × 400 이미지와 도형 코드를 기준으로 실습합니다. 1교시에서 정한 기준점을 사각형의 위치에 적용하고, 타원의 크기 변경, 팔레트 비교, 그리기 순서의 비교·선택을 차례로 수행합니다.

2교시의 실험 예시와 달리 캔버스 크기와 윤곽선 두께는 유지하며, 노트북의 EDIT 표시 영역에서 단계별로 지정한 항목만 수정합니다. 한 속성씩 변경 → 재실행 → 결과 비교 → 변경 이유 기록의 순서로 진행합니다.

참고 자료