# 서울숲_L_Day12 리뷰 레포트
### 참석자
- 이창권, 신철헌, 배형진, 정예원
## 1. 코드 동작 이해
1. 너비 600, 높이 400으로 캔버스를 생성하고 녹색으로 색칠한다.
2. 좌측 상단에 흰색 배경색으로 circle을 그려 얼굴을 만든다.
3. 동일한 반지름 크기로 원호를 그려 입을 만든다.
4. 작은 반지름으로 눈 모양을 만든다.
5. 지름과 같은 크기로 정사각형을 그려 몸통을 만들고 Gradient로 표현한다.
6. 아랫 부분은 검정색 굵은 직선으로 다리 부분을 만들고 오른쪽 다리는 점선으로 변경한다.
```javascript=
ctx.beginPath()
// -> 경로 그리기...
ctx.stroke()
//또는 ctx.fill()
```
7. 간단한 문자열을 얼굴 옆에 그리고 -330도 회전한다.
```javascript=
ctx.translate(450, 70); //중점으로 이동
ctx.rotate((Math.PI/180)*330); // 회전
ctx.translate(-450,-70); // 복귀
```
8. 7개의 직선을 연결하여 화살표 모양을 만들고 화살표 좌측 아래를 기준으로 30도 회전한다.
```javascript=
function drawArrow(x, y) {
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + 70, y);
ctx.lineTo(x + 70, y - 20);
ctx.lineTo(x + 120, y + 10);
ctx.lineTo(x + 70, y + 40);
ctx.lineTo(x + 70, y + 20);
ctx.lineTo(x, y + 20);
ctx.lineTo(x, y);
ctx.fillStyle = 'gray';
ctx.fill();
}
```
9. 화살표 아래에는 유명한 미술작품 이미지를 몸통 정사각형 높이 혹은 너비와 같도록 이미지 비율을 맞춰서 그린다.
```javascript=
function scaleImageSize(img, x, y, len) {
let width, height;
if (img.width > img.height) {
width = len;
height = img.hight * len / img.width;
return [x, y + (len - height) / 2, width, height];
} else {
width = img.width * len / img.height;
height = len;
return [x + (len - width) / 2, y, width, height];
}
}
```
10. 캔버스로 그린 것을 jpg 또는 png 이미지 파일로 저장한다.
```javascript=
function saveToImageFile() {
const out = fs.createWriteStream(__dirname + '/9.png');
const stream = canvas.createPNGStream();
stream.on('data', function (chunk) {
out.write(chunk);
});
}
```
## 2. 코드 동작 개선
`이창권`
- canvas API의 다양한 사용법을 익힐 수 있었다.
- 파일을 저장하고 불러올 때, stream을 사용할 수 있다.
- 엄청 큰 데이터를 다룰 때나, 외부 소스로부터 데이터를 한번에 한 청크(chunk)씩 가져올때 stream을 사용해야 하며, 사용할 줄 알아야 한다.
`신철헌`
- image를 로드해올때 비동기로 구현할 필요가 없었다. 이미지 생성하고 소스 입력하면 알아서 그려주는 것을 팀원들의 코드를 보고 발견했다.
- 도형들을 그리는 로직을 함수로 만들어서 모듈화할 필요가 있다.
- 화살표를 그리는 부분에서 좌표를 직접 계산해서 입력했는데, 좌표를 계산하는부분을 로직으로 구현하는 것이 더 좋을것 겉다.
-
`배형진`
- translate()를 이용하여 회전하고자하는 좌표 기준을 정할 수 있다는 것을 뒤늦게 깨달아 활용하지 못한 점이 아쉽다.
- 이미지 로드할 때 로컬에서 불러오는 것이라서 비동기 처리를 따로 해줄 필요 없었지만 웹에서 이미지를 불러오는 경우 비동기 처리를 해줘야 된다.
`정예원`
- translate로 캔버스의 기준점을 이동 후, restore로 간단히 원점을 기준점으로 돌릴 수 있다.
## 3. Consideration
### 3-1. 스스로 확인할 사항
#### CANVAS API 종류들에 대해 학습하고 정리한다.
`이창권`
- Drawing Shapes
- 기본적으로 beginPath()함수와 closePath(), arc(), moveTo(), lineTo(), fill()함수로 모든 것을 그릴 수가 있다.
- 편하게 사각형을 그릴 때 쓸 수 있는 함수가 존재한다.(fillRect()함수)
- Drawing text
- fillText(), strokeText()함수로 텍스트를 생성할 수 있다.
- Using Images
- new Image()로 Image객체를 생성해 받아온 이미지를 조작할 수 있다.
- drawImage()함수의 인자 개수를 조절해 scaling, slicing을 할 수 있다.
- Transformaitons
- save(), restore()함수로 canvas의 현재상태를 저장하고 복원할 수 있다.
- translate()함수로 canvas의 시작이 되는 origin좌표를 조절할 수 있다.
- rotate(), transform(), scale()함수로 변형이 가능하다.
- Animations
- 기존의 setInterval(),setTimeout()을 사용해도 되지만, requestAnimationFrame을 사용해서 만들 수도 있다.
- Pixel manipulation
- ImageData객체를 이용해 픽셀의 정보를 받아올 수 있고, 해당 픽셀에 대해 다양한 조작이 가능하다
---
`신철헌`
### CANVAS API 종류
- drawing shape
- applying style and color
- drawing text
- using image
- transformation
- compositing and clipping
- 이미지들을 결합하거나 원하는 영역만 잘라서 올릴 수 있다.
- animation
- 시스템(웹브라우져)에서 더 효율적이고 부드러운 에니메이션 실행을 위한 기능 제공
- pixel manipulation
- image에 pixel단위로 접근해서 작업할 수 있다.
- hit regions and accessibliity
- fallback 콘텐츠를 제공하고, 캔버스내에서 이벤트를 반환하기 위한 히트존 기능이 있다.
- optimizing
- 성능과 관련된 기능
-예) offscreen canvas에 그려놓으면 자주 반복되는 작업을 다시 실행할 필요가 없다.
---
`배형진`
- OffscreenCanvas : 캔버스 로직 및 렌더링은 사용자 상호작용과 동일한 스레드에서 일어나므로 애니메이션과 관련된 무거운 계산은 앱의 성능 저하로 이어진다. 이를 개선하기 위한 캔버스 인터페이스이다. 렌더링이 DOM과 완전히 분리되므로 캔버스 간에 동기화가 없으므로 일반 캔버스에 비해 속도가 향상된다.
- Fabric : HTML5 캔버스 요소로 작업하기 쉬운 프레임워크로 캔버스 요소 위에 있는 대화형 객체 모델이며 SVG-to-canvas 파서이기도 하다.
- Konva : 고성능 애니메이션, 전환, 노드 중첩, 레이어, 필터링, 캐싱 데스크톱 및 모바일 애플리케이션을 위한 이벤트 처리 등을 가능하게 해주는 HTML5 Canvas Javascript 프레임워크이다.
---
`정예원`
#### Canvas API 라이브러리
- EaselJS
게임, 생성 예술 및 기타 고도의 그래픽 경험을 쉽게 생성할 수 있게 해주는 오픈소스 캔버스 라이브러리.
- Fabric.js
SVG 파싱 기능을 갖춘 오픈소스 캔버스 라이브러리.
- Konva.js
데스크탑 및 모바일 애플리케이션을 위한 2D 캔버스 라이브러리.
- Phaser
Canvas 및 WebGL 기반의 브라우저 게임을 위한 빠르고 자유로운 오픈소스 프레임워크.
- Scrawl-canvas
2D 캔버스 엘리먼트를 생성하고 조작하기 위한 오픈소스 JavaScript 라이브러리.
- ZIM
canvas에서의 창의적인 코딩을 위한 편의성, 컴포넌트 및 컨트롤을 제공하는 프레임워크.
#### WebGL(Web Graphics Library)
- 플러그인을 사용하지 않고 웹 브라우저에서 상호작용 가능한 3D와 2D 그래픽을 표현하기 위한 자바스크립트 API. HTML5의 <canvas> 요소에서 사용할 수 있는 OpenGL ES 2.0을 대부분 충족하는 API를 제공한다.
### 3-2. 다같이 확인할 사항
#### 1.SVG 개념에 대해 학습하고 CANVAS 2D API와 비교해서 정리한다.
#### 2.다양한 이미지 파일 포맷에 대해 학습하고 정리한다.
`이창권`
#### SVG
- canvas의 성능은 픽셀 수가 많을 경우(>10k)에 좋고, svg의 성능은 픽셀 수가 적을 경우(<10k)에 좋다.
- canvas는 고성능의 애니메이션 작업이나 동영상 조작 등의 작업에 유리하고, svg는 고품질의 문서작업이나 정적 이미지의 조작에 유리하다.
- canvas는 스크립트를 통해서만 작업이 가능하고, svg는 css를 통해서도 작업이 가능하다.
- canvas는 픽셀(pixel) 기반이지만 svg는 모양(shape) 기반이다.
- 같은 픽셀의 화면에 같은 수의 점을 그리는 실험 시, canvas가 HTML이나 SVG보다 훨씬 빠르고 성능이 좋다. 특히 픽셀이 많아질 수록 그 차이는 훨씬 커지며 canvas가 월등히 좋은 성능을 보인다.
#### 다양한 이미지 파일 포맷
- BMP
- 이미지 파일을 무손실 이미지로 저장이 가능하다.
- '반복 문자열 제거' 압축 기법 때문에 호율이 좋지는 않다
- 따라서 용량은 크지만 호환성이 매우 좋다.
- GIF
- 웹 상에서 가장 널리 사용되는 이미지 포맷
- Animation GIF로 움직이는 이미지로 주로 사용된다.
- 비손실 압축, 인덱스 컬러기반의 비트맵 이미지 파일 포멧
- JPEG
- 무손실 압축이 아니지만 하지만 효율적인 압축률을 보여준다.
- 손실은 있지만 원본 이미지와 차이가 크지 않기 때문에 가장 대중적인 포맷
- PNG
- GIF를 대체하기 위해 만들어진 오픈소스 파일 포맷이다.(특허 관련 문제)
- JPEG와 비교해서 무손실 압축이기 때문에 비슷한 색이 넓게 사용될 때 유리하다.
---
`신철헌`
### SVG
- 확장 가능한 벡터 그래픽(Scalable Vector Graphics)는 2차원 그래픽을 표현하기 위해 만들어진 XML파일 형식의 마크업 언어
- 웹 상에 아이콘, 로고, 일러스트레이션 이미지 등에 활용되고, 모든 스크린에서 화질이 선명하며, 최소 용량이고, 편집과 수정이 쉽다는 장점을 지니고 있다.
#### SVG API의 종류
1. 기본 도형 그리기
- 사각형, 원, 타원, 선, 직선의 그룹, 다각형, 경로 등 canvas보다 더 많은 기본 도형을 제공한다.
2. 경로 그리기
- 직선, 곡선, 원호등을 그릴 수 있다.
3. 채우기, 선그리기
- canvas와 달리 CSS를 활용가능하다
4. 그라디언트
5. 패턴
- 보다 자세한 옵션으로 패턴을 반복할 수 있다.
6. 텍스트
- html과 비슷하여, 링크도 넣을 수 있다.
- 텍스트가 작성되는 경로의 모양을 지정가능하다.
7. 단순변형
- 모양 하나 하나별로 지정하고, 캔버스를 이동하고 되돌릴 필요가 없다.
8. clipping masking 가능
9. 필터 기능
- 필터효과를 줄 수 있다.
[출처 1.웹에서 SVG 사용하기 실습 가이드 ](https://svgontheweb.com/ko/#svg)
[출처 2.SVG 튜토리얼 ](https://developer.mozilla.org/ko/docs/Web/SVG/Tutorial)
[출처 3.svg vs canvas](https://medium.com/@benisinca/svg-vs-canvas-92938aff799a)
### 기타 백터 포맷들
#### CGM
- 어떤 특정한 응용 시스템, 플랫폼, 장치 등으로부터 독립된 2D 그래픽 데이터의 교환을 제공한다. 메타파일은 다른 파일을 기술하거나 지정하는 정보를 포함하는 i.e 파일로 그래픽 정보 및 기하학적 원시성을 수용할 수 있다. 국제 표준 규격인 도형 핵심 시스템(GKS)으로 생성된 도형 데이터를 다른 기종 간에 교환하거나 재생하는 것을 목적으로 정의된 표준적인 파일 규격이다. ISO 8632로 지정되었다
[출처 : 위키 백과](https://en.wikipedia.org/wiki/Computer_Graphics_Metafile)
#### 거버 포맷 (RS-274X)
- 거버 포맷(Gerber Format)이란 인쇄 회로 기판 (Printed Circuit Board 또는 PCB) 제작시 사용되는 산업용 소프트웨어에서 가장 많이 사용되는 파일 포맷 형식의 하나이며 인쇄 회로 기판 의 구성요소(동박패턴, 솔더 마스크, 심볼, 마크등의 계층)와 드릴,라우터 (milling) 등의 외형 가공용 데이터를 표현한다.
[출처 : 위키 백과](https://ko.wikipedia.org/wiki/%EA%B1%B0%EB%B2%84_%ED%8F%AC%EB%A7%B7)
---
`배형진`
#### Canvas와 SVG 비교
| Canvas | SVG |
|:---:|:---:|
| 픽셀(pixel) 기반 | 모양(shape) 기반 |
| 단일 HTML 요소 | DOM의 일부분이 되는 다중 그래픽 요소 |
| 스크립트를 통해서만 수정할 수 있음 | 스크립트 및 CSS를 통해서도 수정할 수 있음 |
| 그래픽이 주작업인 게임에 적합 | 렌더링 영역이 넓은 응용 프로그램에 적합 |
#### 다양한 이미지 파일 포맷
- JPEG/JFIF : 사진 이미지를 위해 개발된 형식으로 손실 압축 기법을 사용. 손실 압축으로 압축률을 높일 경우 이미지의 상태가 떨어지는 단점이 있다. 그러나 일반 그래픽 프로그램에서 저장 형식에 있어서 다양해 가장 많이 사용되는 형식
- GIF : 미국의 컴퓨서브사가 개발한 온라인 전송을 위해 만든 그래픽 포맷으로, 색상의 무손실 압축 기술을 사용. LZW 압축 알고리즘을 사용하는데, 넓은 영역에서 한 색을 사용할 경우 압축률이 높아지기 때문에 간단한 도형, 로고, 만화 그림처럼 색이 별로 필요 없는 이미지를 저장하는데 적합
- BMP : 마이크로소프트 사가 개발한 파일 형식으로 압축하지 않은 비트맵 이미지를 저장하는 윈도 OS의 그래픽 파일 형식. 무손실 무압축 포맷이기 때문에 이미지 크기가 크다. 이 포맷의 강점은 간단한 구조와 윈도우 프로그램에서의 호환성이다.
- PNG : GIF를 대체하기 위해 만들어진 자유, 오픈소스 파일 포맷. JPEG와 비교해서 PNG는 이미지안에 비슷한 색이 넓게 사용될 때 유리하다. JPEG가 용량이 더 작아서 최종 배포에 많이 사용되긴 하지만 PNG는 무손실 압축 덕분에 편집 과정에서 쓰이기에 적합
[출처 : 위키백과](https://ko.wikipedia.org/wiki/%EC%9D%B4%EB%AF%B8%EC%A7%80_%ED%8C%8C%EC%9D%BC_%ED%98%95%EC%8B%9D)
---
`정예원`
#### SVG(Scalable Vector Graphics)
- 2차원 벡터 그래픽을 표현하기 위한 XML기반의 파일 형식으로, w3c에서 만든 벡터 이미지 표준.
- SVG 형식의 이미지는 XML 텍스트 파일들로 정의되어 검색화/목록화/스크립트화가 가능하며, 필요하다면 압축도 가능하다.
- SVG의 장점
1. 사이즈에 구애받지 않음
- pixelate 하지 않으므로, 어느 해상도든 대응이 가능하다.
2. 작은 파일 사이즈
- PNG/JEPG과 같은 비트맵 이미지들의 경우, 파일 크기를 결정하는 주요 요소는 해상도이다. 그러나 SVG 그래픽의 경우, 파일 크기를 결정하는 주요 요소는 복잡도이다. 파일 사이즈가 작기 때문에 로딩 시간도 훨씬 줄어든다.
- SVG의 단점
- 그래픽 툴을 통해 적용한 블러/색상조정과 같은 필터를 지원하지 않는다.
- 일부 필터는 지원함.
#### Canvas와 SVG 비교
- Canvas
- 이미지를 raster로 다루기 때문에 해상도 의존적.
- 이벤트 핸들러 지원 안 함.
- 낮은 텍스트 렌더링 능력.
- 결과 이미지는 .png/.jpg로 저장 가능.
- 고도의 그래픽 게임에 적합.
- SVG
- vector로 다루기 때문에 해상도 독립적.
- 이벤트 핸들러 지원.
- 구글 맵스와 같이 대규모 렌더링이 필요한 어플리케이션에 적합.
- 복잡할 경우 렌더링이 느림.
#### 다양한 이미지 파일 포맷
1. BMP
- 비트맵은 디지털 그림을 저장하는 데 쓰이는 그래픽 파일 포맷 중 가장 단순한 구조를 가진 파일 포맷. RGB모드와 Indexed 모드를 지원.
- BMP의 단점들을 개선하기 위해 JEPG, GIF, PNG 등의 다양한 파일 포맷이 개발됨.
- 현재는 BMP를 그대로 사용하기보다 원본 보관용으로 보관하여 파일 포맷을 변환할 때 주로 사용.
- 압축하지 않은 원본은 그대로의 화질을 유지하므로 화질이 매우 우수.
2. JPEG
- 웹 및 멀티미디어 환경에서 가장 널리 사용되고 있는 포맷.
- RGB모드와 CMYK모드를 둘 다 지원.
- RGB 이미지의 모든 컬러 정보 유지.
3. GIF
- 최대 256색까지 저장할 수 있는 비손실 압축 형식.
- 하나의 파일에 여러 비트맵을 저장하여 다중 프레임 애니메이션을 구현할 수 있다.
- 투명 이미지를 지원.
- 특별한 플러그인 없이 여러 환경에서 애니메이션을 쉽게 적용할 수 있다.
4. PNG
- GIF 포맷을 대체하기 위해 개발된 파일 포맷으로, GIF와 JPEG의 장점을 합친 파일 포맷.
- 비손실 압축방식으로 원본에 손상 없이 파일의 크기를 줄여줌.
- 이미지의 모든 컬러정보와 알파 채널을 보존해 포토샵에서 활용하기 용이.
- 문자나 날카로운 경계가 있는 이미지의 경우, JPG보다 PNG가 효과적.