2021/04/01(목)
슬라이드 화면구현과 각각의 메인화면의 뒷배경은 아래 글을 보고 참고
https://cordingdoah.tistory.com/81
https://cordingdoah.tistory.com/85
<영상처리 알고리즘>
- 이번에는 각각 메인화면에서 사진을 가져와서 캔버스에 영상처리를 적용하는 알고리즘을 구현하는 것을 리뷰해보겠다
알고리즘 구현에 앞서 영상처리를 어떤 과정을 통해 웹에 구현이 되는지 구성도를 보자!
1. 디스크의 있는 raw(흑백파일)을 가져온다
2. 사진의 크기에 맞게 inImageArray 생성 후
3. 사진의 픽셀이 inImageArray 배열형태로 들어오게 된다
4. 영상처리 알고리즘을 통해 각 픽셀이 처리
5. outImageArray 배열에 저장되고 saveImage()함수를 통해 디스크에 저장
6. displayImage() 함수를 통해 화면에 출력
--> 이러한 과정을 가지고 처리된 영상이 화면에 출력되는 것을 알 수 있음
자! 이제 영상처리를 구현하는 알고리즘을 코딩해보자
먼저 화면에 출력해줄 캔버스를 만들어 주자 outCanvas에 영상처리된 사진을 출력하겠다
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@700&display=swap" rel="stylesheet">
<script type="module" src="./app.js" defer>
</script>
<script>
var inFile;
var inImageArray, inWidth, inHeight;
var outCanvas, outCtx, outImageArray;
var outWidth, outHeight, outPaper;
//초기화 : 캔버스 생성
function init() {
outCanvas = document.getElementById('outCanvas');
outCtx = outCanvas.getContext('2d');
}
</script>
</head>
<body>
<div class="canvasEdge">
<div class="KHC">
<canvas id="outCanvas" width="100" height="100" style="background: rgba(0, 0, 0, 0);"></canvas>
</div>
</div>
</body>
</html>
이제부터 진짜! 알고리즘
<파일 선택>
-파일을 선택하면 배열에 저장하고 출력하는 메소드
//파일 선택 메소드
function selectRawFile() {
init();
inFile = document.getElementById('selectFile').files[0];
// 중요! 코드 (영상의 크기를 파악)
inWidth = inHeight = Math.sqrt(inFile.size);
// 입력 2차원 배열을 준비
inImageArray = new Array(inHeight); // 1차원 배열
for (var i = 0; i < inHeight; i++) // 2차원 배열
inImageArray[i] = new Array(inWidth);
// RAW 파일 --> 2차원 배열
var reader = new FileReader();
reader.readAsBinaryString(inFile);
reader.onload = function () {
var bin = reader.result; // 파일을 덩어리(bin)로 읽었음
// 덩어리(bin)에서 한점한점씩 뽑아서, 배열에 넣기
for (var i = 0; i < inHeight; i++) {
for (var k = 0; k < inWidth; k++) {
var sPixel = (i * inHeight + k);
var ePixel = (i * inHeight + k) + 1;
inImageArray[i][k] = bin.slice(sPixel, ePixel); // 1개픽셀-->배열
}
}
equalImage();
}
}
사진 파일을 inImageArray(원본)에 넣어놓고 영상처리를 할 수 있도록 구현하기 위해
<원본이미지>
- inImageArray에 저장된 사진 파일의 원본을 outImageArray에 그대로 넣어줌
//원본 출력
function equalImage() { //동일 영상 알고리즘
outHeight = inHeight;
outWidth = inWidth;
// 출력 2차원 배열을 준비
outImageArray = new Array(outHeight); // 256짜리 1차원 배열
for (var i = 0; i < outHeight; i++)
outImageArray[i] = new Array(outWidth);
// ***** 진짜 영상처리 알고리즘 *****
for (var i = 0; i < inHeight; i++) {
for (var k = 0; k < inWidth; k++) {
outImageArray[i][k] = inImageArray[i][k];
}
}
displayImage();
}
<화면 출력>
- 저장된 outImageArray 배열을 캔버스에 출력해주는 메소드
//캔버스에 이미지 출력
function displayImage() {
// 캔버스 크기를 결정
outCanvas.width = outWidth;
outCanvas.height = outHeight;
outPaper = outCtx.createImageData(outHeight, outWidth); //종이 붙였음.
for (var i = 0; i < outHeight; i++) {
for (var k = 0; k < outWidth; k++) {
var charValue = outImageArray[i][k].charCodeAt(0); // 깨진문자를 숫자로.
outPaper.data[(i * outWidth + k) * 4 + 0] = charValue; // R
outPaper.data[(i * outWidth + k) * 4 + 1] = charValue; // G
outPaper.data[(i * outWidth + k) * 4 + 2] = charValue; // B
outPaper.data[(i * outWidth + k) * 4 + 3] = 255; // Alpha
}
}
outCtx.putImageData(outPaper, 0, 0);
}
위까지 구현한 결과
파일을 가져오면 캔버스 화면에 배열의 형태로 띄울수 있다
raw파일 색표현(참고)
<밝게하기>
//밝게하기
function brighteImage() {
clickEventDown();
// ***** 진짜 영상처리 알고리즘 *****
var value = parseInt(prompt("밝게할 값", "0"));
for (var i = 0; i < outHeight; i++) {
for (var k = 0; k < outWidth; k++) {
// 문자 --> 숫자
pixel = outImageArray[i][k].charCodeAt(0);
// **** 요기가 핵심 알고리즘. (밝게하기)
if (pixel + value > 255)
pixel = 255;
else
pixel += value;
// 숫자 --> 문자
outImageArray[i][k] = String.fromCharCode(pixel);
}
}
displayImage();
clickEvent();
}
1. prompt로 얼마나 밝게할 것인지 받아오기 초기값은 0
2. 2차원 사진 배열의 크기만큼 이중 반복문
3. 각각의 배열의 요소를 숫자로 바꿔서 pixel변수에 저장
4. pixel과 밝게하고 싶은 값을 더해서 최대 밝은 값인 255보다 크면 255로 지정
5. 255보다 작으면 pixel과 밝게하고 싶은 값을 더함
6. 결과값을 다시 문자로 바꿔서 배열에 저장
7. displayImage() 함수를 통해 배열을 출력
** clickEventDown, clickEvent는 캔버스를 클릭했을 때 영상이 적용된 것과 원본 화면과 비교할 수 있도록 만든 이벤트인데 다른 게시물에서 다루도록 하겠다
--> 100를 밝게한 결과 화면
<흑백처리>
//어둡게 하기
function darkImage() {
clickEventDown();
// ***** 진짜 영상처리 알고리즘 *****
//평균값을 도출
var valueSum = 0;
for (var i = 0; i < outHeight; i++) {
for (var k = 0; k < outWidth; k++) {
// 문자 --> 숫자
pixel = outImageArray[i][k].charCodeAt(0);
valueSum += pixel;
}
}
var value = valueSum / (outHeight * outWidth);
//평균값만큼 흑백처리
for (var i = 0; i < outHeight; i++) {
for (var k = 0; k < outWidth; k++) {
// 문자 --> 숫자
pixel = outImageArray[i][k].charCodeAt(0);
// **** 요기가 핵심 알고리즘. 흑백처리
if (pixel > value)
pixel = 255;
else
pixel = 0;
// 숫자 --> 문자
outImageArray[i][k] = String.fromCharCode(pixel);
}
}
displayImage();
clickEvent()
}
어둡게 처리하기 같은 경우는 밝게하기와 다르게 사진의 평균값을 도출해 평균값보다 값이 크면 흰색 어두우면 검은색으로 처리
1. 평균값을 구하기 위해 모든 배열의 값을 더하고 크기만큼 나눠서 평균값 구하기
2. 각 배열의 요소(pixel)값이 평균값보다 높으면(채도가 밝으면) 255(흰색)으로 처리
3. 각 배열의 요소(pixel)값이 평균값보다 낮으면(채도가 어두우면) 0(검은색)으로 처리
4. 배열에 저장
5. displayImage로 출력
-->흑백처리 결과
다음 게시물에서 영상처리 알고리즘 계속...☺
'코딩 연습장 > Javascript' 카테고리의 다른 글
자바스크립트를 이용한 개인 프로젝트 - 7(영상 처리 알고리즘) (0) | 2021.06.15 |
---|---|
자바스크립트를 이용한 개인 프로젝트 - 6(영상 처리 알고리즘) (0) | 2021.06.14 |
자바스크립트를 이용한 개인 프로젝트 - 4(코코coco 화면) (0) | 2021.06.13 |
자바스크립트를 이용한 개인 프로젝트 - 3(업up 화면) (0) | 2021.06.13 |
자바스크립트를 이용한 개인 프로젝트 - 2(인어 공주 화면) (0) | 2021.06.11 |