검색결과 리스트
글
문제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 | 프로그램 종료 |
#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 |
graphic_editor.c