문제5 그래픽편집기

알고리즘.데이터구조 2011. 2. 18. 11:41


이미지를 M X N 배열로 표현하는 간단한 대화형 그래픽 편집기  프로그램을 만들어보자.

 

 입력

한 줄에 하나씩의 1개 문자의 명령으로 구성됨.  매개변수는 스페이스로 분리됨 

픽셀좌표는 1 이상 M이하의 열, 1이상 N이하의 행 으로 표현됨. 

표의 왼쪽 위 꼭지점이 원점이며, 색은 대문자로 지정함 

 

 

출력

명령을 제외한 문자는 무시하고,  S Name 명령은 Name 으로 주어진 파일명 출력 후

현재 이미지 내용을 출력함.

 

I M N   M X N 이미지를 새로 생성 후, 흰색(O)으로 초기화
C  모든 픽셀을 흰색으로 칠한다
L X Y C  (X, Y) 픽셀을 주어진 색(C)로 칠한다
V X Y1 Y2 C  X열에 Y1행과 Y2행 (Y1, Y2포함)사이에 색(C)으로 수직방향 직선을 그린다 
H X1 X2 Y C  Y행에 X1열과 X2행(X1, X2포함)사이에 색(C)으로 수평방향 직선을 그린다
K X1 Y1 X2 Y2 C  주어진 색(C)로 채워진 직사각형을 그리되, X1 Y1은 왼쪽 위끝점 X2 Y2는 오른쪽 아래 끝점
F X Y C  R영역을 색 C로 채운다. R 영역은 X Y 점이 포함되고, 해당 점과 상 하 좌 우  이웃하는 점이 R영역으로 포함된다.
S Name  파일명을 입력받은 대로 출력 후, 현재 이미지 내용을 출력한다.
X  프로그램 종료 


 



graphic_editor.c


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_SIZE 100

typedef struct _Image {
	char *pixels;
	int r, c;
} Image;

typedef struct _Point {
	int x, y;
} Point;


Point make_point(int x, int y);

 
Image* initiate(int row, int col);
void fill_color(Image *image, Point point, char color);
void show(Image *image);
void flood(Image *image, Point point, char color);
void flood_recur(Image *image, Point point, char color, char r_color); 
void horizontal_line(Image *image, int x, int y1, int y2, char color);
void vertical_line(Image *image, int x1, int x2, int y, char color);
void rectangle(Image *image, Point left_top, Point right_bottom, char color);
void clear(Image *image, char color);


int main (int argc, char const* argv[])
{
	char cmd, color;
	char buf[MAX_SIZE], name[MAX_SIZE];
	int m, n, x1, x2, y1, y2;
	Image *image = 0;

	while (fgets(buf, 100, stdin) != NULL && strncmp(buf, "X", 1) != 0) {
	 	if (strncmp(buf, "I ", 2) == 0) {
		
			sscanf(buf, "%c %d %d", &cmd, &m, &n);
			image = initiate(n, m);
			
		} else if (strncmp(buf, "C", 1) == 0) {\
	
			clear(image, '0');
			
		} else if (strncmp(buf, "L ", 2) == 0) {
			
			sscanf(buf, "%c %d %d %c", &cmd, &x1, &y1, &color);
			fill_color(image, make_point(x1-1, y1-1), color);	
			
		} else if (strncmp(buf, "V ", 2) == 0) {
			
			sscanf(buf, "%c %d %d %d %c", &cmd, &x1, &y1, &y2, &color);
			vertical_line(image, x1-1, y1-1, y2-1, color);
			
		} else if (strncmp(buf, "H ", 2) == 0) {
			
			sscanf(buf, "%c %d %d %d %c", &cmd, &x1, &x2, &y1, &color);
			horizontal_line(image, x1-1, x2-1, y1-1, color);
			
		} else if (strncmp(buf, "K ", 2) == 0) {
			
			sscanf(buf, "%c %d %d %d %d %c", &cmd, &x1, &y1, &x2, &y2, &color);
			rectangle(image, make_point(x1-1, y1-1), make_point(x2-1, y2-1), color);
			
		} else if (strncmp(buf, "F ", 2) == 0) {
		
			sscanf(buf, "%c %d %d %c", &cmd, &x1, &y1, &color);
			flood(image, make_point(x1-1, y1-1), color);
			
		} else if (strncmp(buf, "S ", 2) == 0) {
			
			sscanf(buf, "%c %s", &cmd, name);
			printf("%s \n", name);
			show(image);
		}
	}
	
	return 0;
}

Point make_point(int x, int y) {
	return (Point){x, y};
}



// 이미지 생성 - I m n 
Image* initiate(int row, int col) {
	Image *image = (Image*)malloc(sizeof(Image));
	
	image->pixels = (char*)malloc(row*col); 
	image->r = row;
	image->c = col;
	
	clear(image, '0');
	
	return image;
}

// 주어진 픽셀에 칠하기 - L x y c
void fill_color(Image *image, Point point, char color) {
	image->pixels[point.y*image->c +  point.x] = color;
}

// 이미지 출력 
void show(Image *image) {
	int i;
	
	for (i = 0; i < image->r * image->c; i++) {
		putchar(image->pixels[i]);
		
		if (i % image->c == image->c - 1) {
			putchar('\n');
		}
	}
}

// 점람 채우기 
void flood(Image *image, Point point, char color) {
	char r_color = image->pixels[point.y*image->c +  point.x];
	flood_recur(image, point, color, r_color);
}


void flood_recur(Image *image, Point point, char color, char r_color) {
	int x = point.x;
	int y = point.y;
	int index = y*image->c + x;
	
	// 경계를 벗어났거나 같은 영역이 아니면 종료 
	if (image->pixels[index] != r_color || x < 0 || y < 0 || x >= image->c || y >= image->r) {
		return;
	}
	image->pixels[index] = color;
	
	flood_recur(image, make_point(x, y+1), color, r_color);
	flood_recur(image, make_point(x+1, y), color, r_color);
	flood_recur(image, make_point(x, y-1), color, r_color);
	flood_recur(image, make_point(x-1, y), color, r_color);
}


// 수평 직선  - H
void vertical_line(Image *image, int x, int y1, int y2, char color) {
	Point left_top, right_bottom;
	
	left_top.x = right_bottom.x = x;
	left_top.y = y1;
	right_bottom.y = y2;
	
	rectangle(image, left_top, right_bottom, color);
}


// 수직 직선  - V
void horizontal_line(Image *image, int x1, int x2, int y, char color) {
	Point left_top, right_bottom;
	
	left_top.x = x1;
	right_bottom.x = x2;
	left_top.y = right_bottom.y = y;
	
	rectangle(image, left_top, right_bottom, color);
}

// 사각형 그리고 채우기 - K
void rectangle(Image *image, Point left_top, Point right_bottom, char color) {
	int i, j;
	
	for (i = left_top.y; i <= right_bottom.y; i++) {
		for (j = left_top.x; j <= right_bottom.x; j++) {
			image->pixels[i*image->c + j] = color;
		}
	}
}


void clear(Image *image, char color) {
	int i;
	for (i = 0; i < image->r * image->c; i++) {
		image->pixels[i] = color;
	}
}



'알고리즘.데이터구조' 카테고리의 다른 글

합병정렬(Merge Sort)  (0) 2011.03.23
HMAC-SHA1  (0) 2011.03.11
문제5 그래픽편집기  (0) 2011.02.18
문제4 LCD디스플레이  (0) 2011.02.18
문제3 여행  (0) 2011.02.18
문제2 지뢰찾기  (0) 2011.02.18