HTML5+ CSS3+ Javascript

6일차

구자룡 2021. 3. 23. 18:12

0323미션.html
0.04MB

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title> 영상처리 (Beta 7) </title>
    <script>
        // 전역 변수(*중요*)
        var outCanvas, outCtx, inFile;  // 캔버스 관련
        var outPaper; // 캔버스에는 한점한점이 안찍힘. 대신 캔버스에 종이를 붙임.

        var inImageArray, outImageArray;  // 입력 파일 및 배열
        var inWidth, inHeight, outWidth, outHeight;  // 입력 영상의 폭과 높이

        // *** 공통 함수 모음 ***
        function init() {
            outCanvas = document.getElementById('outCanvas');
            outCtx = outCanvas.getContext('2d');
        }
        function openImage() {
            inFile = document.getElementById('selectFile').files[0];
            // 중요! 코드 (영상의 크기를 파악)
            inWidth = inHeight = Math.sqrt(inFile.size);
            // 입력 2차원 배열을 준비
            inImageArray = new Array(inHeight); // 512짜리 1차원 배열
            for (var i = 0; i < inHeight; i++)
                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();
            }

        }
        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);
        }

        function ImageProcessing(selectNum) { // 선택번호를 받음.
            switch (selectNum.value) {
                case "1": // 동일 영상
                    equalImage(); break;
                case "2": // 밝게 하기
                    addImage(); break;
                case "4": // 흑백 
                    bwImage(); break;
                case "5": // 흑백(평균값)
                    bwImageAvg(); break;
            }
        }
        function ImageProcessing1(selectNum) { // 선택번호를 받음.
            switch (selectNum.value) {
                case "21": // 축소
                    zoomOutImage(); break;
                case "22": // 확대
                    zoomInImage(); break;
            }
        }
        function ImageProcessing2(selectNum) { // 선택번호를 받음.
            switch (selectNum.value) {
                case "41": // 히스토그램 스트래칭
                    histoStretch(); break;
                case "42": // 엔드-인 탐색
                    endInSearch(); break;
                case "43": // 히스토그램 평활화
                    histoEqual(); break;
            }
        }
        function ImageProcessing3(selectNum) { // 선택번호를 받음.
            switch (selectNum.value) {
                case "61": // 엠보싱
                    embossImage(); break;
                case "62": // 블러링
                    blurrImage(); break;
                case "63": // 샤프닝
                    spImage(); break;
                case "64": // 가우시안
                    gauImage(); break;
                case "65": // 경계선 처리
                    lineImage(); break;
                case "66": // 고주파 처리
                    goImage(); break;
                case "67": // 저주파 처리
                    juImage(); break;
                case "68": // 라플라시안 처리
                    lapImage(); break;


            }
        }

        // *** 영상처리 함수 모음 ***
        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();
        }
        function addImage() {  // 영상 밝게하기 알고리즘
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            var value = parseInt(prompt("밝게할 값", "0"));
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    // 문자 --> 숫자
                    pixel = inImageArray[i][k].charCodeAt(0);
                    // **** 요기가 핵심 알고리즘. (밝게하기)
                    if (pixel + value > 255)
                        pixel = 255;
                    else
                        pixel += value;
                    // 숫자 --> 문자
                    outImageArray[i][k] = String.fromCharCode(pixel);
                }
            }
            displayImage();
        }
        function bwImage() { // 흑백영상 알고리즘
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            var value = parseInt(prompt("기준 값", "127"));
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    // 문자 --> 숫자
                    pixel = inImageArray[i][k].charCodeAt(0);
                    // **** 요기가 핵심 알고리즘. (흑백)
                    if (pixel > value)
                        pixel = 255;
                    else
                        pixel = 0;
                    // 숫자 --> 문자
                    outImageArray[i][k] = String.fromCharCode(pixel);
                }
            }
            displayImage();
        }
        function bwImageAvg() {
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            var hap = 0;
            for (var i = 0; i < inHeight; i++)
                for (var k = 0; k < inWidth; k++)
                    hap += inImageArray[i][k].charCodeAt(0);
            var value = hap / (inHeight * inWidth);

            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    // 문자 --> 숫자
                    pixel = inImageArray[i][k].charCodeAt(0);
                    // **** 요기가 핵심 알고리즘. (흑백)
                    if (pixel > value)
                        pixel = 255;
                    else
                        pixel = 0;
                    // 숫자 --> 문자
                    outImageArray[i][k] = String.fromCharCode(pixel);
                }
            }
            displayImage();
        }


        function zoomOutImage() {
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            var scale = parseInt(prompt("축소 배율(짝수)", "2"));
            outHeight = parseInt(inHeight / scale);
            outWidth = parseInt(inWidth / scale);
            // 출력 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[parseInt(i / scale)][parseInt(k / scale)] = inImageArray[i][k];
                }
            }
            displayImage();
        }
        function zoomInImage() {
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            var scale = parseInt(prompt("확대 배율(짝수)", "2"));
            outHeight = inHeight * scale;
            outWidth = inWidth * scale;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);
            // outImageArray를 초기화 시키기 (0으로 채우기)
            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++)
                    outImageArray[i][k] = String.fromCharCode(0);

            // ***** 진짜 영상처리 알고리즘 *****
            for (var i = 0; i < outHeight; i++) {
                for (var k = 0; k < outWidth; k++) {
                    // **** 요기가 핵심 알고리즘. (영상 축소)
                    outImageArray[i][k] = inImageArray[parseInt(i / scale)][parseInt(k / scale)];
                }
            }
            displayImage();
        }
        function histoStretch() { // 히스토그램 스트래칭
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            //  out =  ( in - low ) / ( high - low ) * 255
            var low = inImageArray[0][0].charCodeAt(0);
            var high = inImageArray[0][0].charCodeAt(0);
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    pixel = inImageArray[i][k].charCodeAt(0);
                    if (pixel < low)
                        low = pixel;
                    if (pixel > high)
                        high = pixel
                }
            }
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    // 문자 --> 숫자
                    inVal = inImageArray[i][k].charCodeAt(0);
                    // **** 요기가 핵심 알고리즘.
                    outVal = (inVal - low) / (high - low) * 255;
                    // 숫자 --> 문자
                    outImageArray[i][k] = String.fromCharCode(outVal);
                }
            }
            displayImage();
        }
        function endInSearch() {
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            //  out =  ( in - low ) / ( high - low ) * 255
            var low = inImageArray[0][0].charCodeAt(0);
            var high = inImageArray[0][0].charCodeAt(0);
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    pixel = inImageArray[i][k].charCodeAt(0);
                    if (pixel < low)
                        low = pixel;
                    if (pixel > high)
                        high = pixel
                }
            }
            low += 50;
            high -= 50;

            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    // 문자 --> 숫자
                    inVal = inImageArray[i][k].charCodeAt(0);
                    // **** 요기가 핵심 알고리즘. (흑백)
                    outVal = (inVal - low) / (high - low) * 255;
                    if (outVal > 255)
                        outVal = 255;
                    else if (outVal < 0)
                        outVal = 0;

                    // 숫자 --> 문자
                    outImageArray[i][k] = String.fromCharCode(outVal);
                }
            }
            displayImage();
        }
        function histoEqual() {
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            // 1단계 : 히스토그램 생성
            histo = new Array(256);
            for (var i = 0; i < 256; i++)
                histo[i] = 0;
            for (var i = 0; i < inHeight; i++)
                for (var k = 0; k < inWidth; k++) {
                    value = inImageArray[i][k].charCodeAt(0);
                    histo[value]++;
                }
            // 2단계 : 누적 히스토그램 생성
            sumHisto = new Array(256);
            for (var i = 0; i < 256; i++)
                sumHisto[i] = 0;
            sumVal = 0;
            for (var i = 0; i < 256; i++) {
                sumVal += histo[i];
                sumHisto[i] = sumVal;
            }
            // 3단계 : 정규화된 누적히스토그램
            // ns = s * (1/픽셀총수) * 화소최대밝기
            normalHisto = new Array(256);
            for (var i = 0; i < 256; i++)
                normalHisto[i] = 0.0;
            for (var i = 0; i < 256; i++)
                normalHisto[i] = sumHisto[i] * (1 / (inWidth * inHeight)) * 255;

            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    // 문자 --> 숫자
                    inVal = inImageArray[i][k].charCodeAt(0);
                    // **** 요기가 핵심 알고리즘. (흑백)
                    outVal = normalHisto[inVal];
                    if (outVal > 255)
                        outVal = 255;
                    else if (outVal < 0)
                        outVal = 0;
                    else
                        outVal = parseInt(outVal);
                    // 숫자 --> 문자
                    outImageArray[i][k] = String.fromCharCode(outVal);
                }
            }
            displayImage();
        }
        function embossImage() {  // 엠보싱 알고리즘
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            //// 화소 영역 처리
            var mask = [[-1., 0., 0.],
            [0., 0., 0.],
            [0., 0., 1.]]
            // 임시 입력 배열
            tempInputArray = new Array(inHeight + 2); // 2칸 큼
            for (var i = 0; i < inHeight + 2; i++)
                tempInputArray[i] = new Array(inWidth + 2);
            // 임시 입력 배열 초기화
            for (var i = 0; i < inHeight + 2; i++)
                for (var k = 0; k < inWidth + 2; k++)
                    tempInputArray[i][k] = String.fromCharCode(127);
            // 입력 배열 --> 임시 입력
            for (var i = 0; i < inHeight; i++)
                for (var k = 0; k < inWidth; k++) {
                    tempInputArray[i + 1][k + 1] = inImageArray[i][k];
                }
            // 임시 출력 배열
            tempOutputArray = new Array(outHeight); //
            for (var i = 0; i < outHeight; i++)
                tempOutputArray[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    var S = 0.0;
                    for (var m = 0; m < 3; m++) {
                        for (var n = 0; n < 3; n++) {
                            S += mask[m][n] * tempInputArray[i + m][k + n].charCodeAt(0);
                        }
                    }
                    tempOutputArray[i][k] = S;
                }
            }
            // 만약, 마스크의 합계가 0이면, 결과를 127 더하자.
            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++)
                    tempOutputArray[i][k] += 127.0;

            // 임시 출력 --> 진짜 출력 배열
            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    var v = tempOutputArray[i][k];
                    if (v > 255.0)
                        v = 255.0;
                    if (v < 0)
                        v = 0.0;
                    outImageArray[i][k] = String.fromCharCode(v);
                }
            displayImage();
        }
        function blurrImage() {  // 블러링 알고리즘
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            //// 화소 영역 처리
            var mask = [[1 / 9., 1 / 9., 1 / 9.],
            [1 / 9., 1 / 9., 1 / 9.],
            [1 / 9., 1 / 9., 1 / 9.]]
            // 임시 입력 배열
            tempInputArray = new Array(inHeight + 2); // 2칸 큼
            for (var i = 0; i < inHeight + 2; i++)
                tempInputArray[i] = new Array(inWidth + 2);
            // 임시 입력 배열 초기화
            for (var i = 0; i < inHeight + 2; i++)
                for (var k = 0; k < inWidth + 2; k++)
                    tempInputArray[i][k] = String.fromCharCode(127);
            // 입력 배열 --> 임시 입력
            for (var i = 0; i < inHeight; i++)
                for (var k = 0; k < inWidth; k++) {
                    tempInputArray[i + 1][k + 1] = inImageArray[i][k];
                }
            // 임시 출력 배열
            tempOutputArray = new Array(outHeight); //
            for (var i = 0; i < outHeight; i++)
                tempOutputArray[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    var S = 0.0;
                    for (var m = 0; m < 3; m++) {
                        for (var n = 0; n < 3; n++) {
                            S += mask[m][n] * tempInputArray[i + m][k + n].charCodeAt(0);
                        }
                    }
                    tempOutputArray[i][k] = S;
                }
            }
            // 만약, 마스크의 합계가 0이면, 결과를 127 더하자.
            // for(var i=0; i<outHeight; i++) 
            //     for (var k=0; k<outWidth; k++) 
            //         tempOutputArray[i][k] += 127.0;

            // 임시 출력 --> 진짜 출력 배열
            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    var v = tempOutputArray[i][k];
                    if (v > 255.0)
                        v = 255.0;
                    if (v < 0)
                        v = 0.0;
                    outImageArray[i][k] = String.fromCharCode(v);
                }
            displayImage();
        }
        function spImage() {  // 블러링 알고리즘
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            //// 화소 영역 처리
            var mask = [[0., -1., 0.], [-1., 5., -1.], [0., -1., 0.]];

            // 임시 입력 배열
            tempInputArray = new Array(inHeight + 2); // 2칸 큼
            for (var i = 0; i < inHeight + 2; i++)
                tempInputArray[i] = new Array(inWidth + 2);
            // 임시 입력 배열 초기화
            for (var i = 0; i < inHeight + 2; i++)
                for (var k = 0; k < inWidth + 2; k++)
                    tempInputArray[i][k] = String.fromCharCode(127);
            // 입력 배열 --> 임시 입력
            for (var i = 0; i < inHeight; i++)
                for (var k = 0; k < inWidth; k++) {
                    tempInputArray[i + 1][k + 1] = inImageArray[i][k];
                }
            // 임시 출력 배열
            tempOutputArray = new Array(outHeight); //
            for (var i = 0; i < outHeight; i++)
                tempOutputArray[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    var S = 0.0;
                    for (var m = 0; m < 3; m++) {
                        for (var n = 0; n < 3; n++) {
                            S += mask[m][n] * tempInputArray[i + m][k + n].charCodeAt(0);
                        }
                    }
                    tempOutputArray[i][k] = S;
                }
            }
            // 만약, 마스크의 합계가 0이면, 결과를 127 더하자.
            // for(var i=0; i<outHeight; i++) 
            //     for (var k=0; k<outWidth; k++) 
            //         tempOutputArray[i][k] += 127.0;

            // 임시 출력 --> 진짜 출력 배열
            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    var v = tempOutputArray[i][k];
                    if (v > 255.0)
                        v = 255.0;
                    if (v < 0)
                        v = 0.0;
                    outImageArray[i][k] = String.fromCharCode(v);
                }
            displayImage();
        }
        function gauImage() {  // 블러링 알고리즘
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            //// 화소 영역 처리
            var mask = [[1. / 16., 1. / 8., 1. / 16.], [1. / 8., 1. / 4., 1. / 8.], [1. / 16., 1. / 8., 1. / 16.]];

            // 임시 입력 배열
            tempInputArray = new Array(inHeight + 2); // 2칸 큼
            for (var i = 0; i < inHeight + 2; i++)
                tempInputArray[i] = new Array(inWidth + 2);
            // 임시 입력 배열 초기화
            for (var i = 0; i < inHeight + 2; i++)
                for (var k = 0; k < inWidth + 2; k++)
                    tempInputArray[i][k] = String.fromCharCode(127);
            // 입력 배열 --> 임시 입력
            for (var i = 0; i < inHeight; i++)
                for (var k = 0; k < inWidth; k++) {
                    tempInputArray[i + 1][k + 1] = inImageArray[i][k];
                }
            // 임시 출력 배열
            tempOutputArray = new Array(outHeight); //
            for (var i = 0; i < outHeight; i++)
                tempOutputArray[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    var S = 0.0;
                    for (var m = 0; m < 3; m++) {
                        for (var n = 0; n < 3; n++) {
                            S += mask[m][n] * tempInputArray[i + m][k + n].charCodeAt(0);
                        }
                    }
                    tempOutputArray[i][k] = S;
                }
            }
            // 만약, 마스크의 합계가 0이면, 결과를 127 더하자.
            // for(var i=0; i<outHeight; i++) 
            //     for (var k=0; k<outWidth; k++) 
            //         tempOutputArray[i][k] += 127.0;

            // 임시 출력 --> 진짜 출력 배열
            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    var v = tempOutputArray[i][k];
                    if (v > 255.0)
                        v = 255.0;
                    if (v < 0)
                        v = 0.0;
                    outImageArray[i][k] = String.fromCharCode(v);
                }
            displayImage();
        }
        function lineImage() {  // 블러링 알고리즘
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            //// 화소 영역 처리
            var maskW = [[0., 0., 0.], [0., 1., 0.], [0., 0., 0.]];
            var maskH = [[1., 1., 1.], [1., -8., 1.], [1., 1., 1.]];

            // 임시 입력 배열
            tempInputArrayW = new Array(inHeight + 2); // 2칸 큼
            for (var i = 0; i < inHeight + 2; i++)
                tempInputArrayW[i] = new Array(inWidth + 2);
            // 임시 입력 배열 초기화
            for (var i = 0; i < inHeight + 2; i++)
                for (var k = 0; k < inWidth + 2; k++)
                    tempInputArrayW[i][k] = String.fromCharCode(127);
            // 입력 배열 --> 임시 입력
            for (var i = 0; i < inHeight; i++)
                for (var k = 0; k < inWidth; k++) {
                    tempInputArrayW[i + 1][k + 1] = inImageArray[i][k];
                }
            // 임시 출력 배열
            tempOutputArrayW = new Array(outHeight); //
            for (var i = 0; i < outHeight; i++)
                tempOutputArrayW[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    var S = 0.0;
                    for (var m = 0; m < 3; m++) {
                        for (var n = 0; n < 3; n++) {
                            S += maskW[m][n] * tempInputArrayW[i + m][k + n].charCodeAt(0);
                        }
                    }
                    tempOutputArrayW[i][k] = S;
                }
            }
            tempInputArrayH = new Array(inHeight + 2); // 2칸 큼
            for (var i = 0; i < inHeight + 2; i++)
                tempInputArrayH[i] = new Array(inWidth + 2);
            // 임시 입력 배열 초기화
            for (var i = 0; i < inHeight + 2; i++)
                for (var k = 0; k < inWidth + 2; k++)
                    tempInputArrayH[i][k] = String.fromCharCode(127);
            // 입력 배열 --> 임시 입력
            for (var i = 0; i < inHeight; i++)
                for (var k = 0; k < inWidth; k++) {
                    tempInputArrayH[i + 1][k + 1] = inImageArray[i][k];
                }
            // 임시 출력 배열
            tempOutputArrayH = new Array(outHeight); //
            for (var i = 0; i < outHeight; i++)
                tempOutputArrayH[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    var S = 0.0;
                    for (var m = 0; m < 3; m++) {
                        for (var n = 0; n < 3; n++) {
                            S += maskH[m][n] * tempInputArrayH[i + m][k + n].charCodeAt(0);
                        }
                    }
                    tempOutputArrayH[i][k] = S;
                }
            }
            tempOutputArray = new Array(outHeight); //
            for (var i = 0; i < outHeight; i++)
                tempOutputArray[i] = new Array(outWidth);

            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    tempOutputArray[i][k] = Math.sqrt(Math.pow(tempOutputArrayW[i][k], 2) + Math.pow(tempOutputArrayH[i][k], 2));
                }

            // 만약, 마스크의 합계가 0이면, 결과를 127 더하자.
            // for(var i=0; i<outHeight; i++) 
            //     for (var k=0; k<outWidth; k++) 
            //         tempOutputArray[i][k] += 127.0;

            // 임시 출력 --> 진짜 출력 배열
            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    var v = tempOutputArray[i][k];
                    if (v > 255.0)
                        v = 255.0;
                    if (v < 0)
                        v = 0.0;
                    outImageArray[i][k] = String.fromCharCode(v);
                }
            displayImage();
        }
        function goImage() {  // 블러링 알고리즘
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            //// 화소 영역 처리
            var mask = [[-1. / 9., -1. / 9., -1. / 9.], [-1. / 9., 8. / 9., -1. / 9.], [-1. / 9., -1. / 9., -1. / 9.]];
            // 임시 입력 배열
            tempInputArray = new Array(inHeight + 2); // 2칸 큼
            for (var i = 0; i < inHeight + 2; i++)
                tempInputArray[i] = new Array(inWidth + 2);
            // 임시 입력 배열 초기화
            for (var i = 0; i < inHeight + 2; i++)
                for (var k = 0; k < inWidth + 2; k++)
                    tempInputArray[i][k] = String.fromCharCode(127);
            // 입력 배열 --> 임시 입력
            for (var i = 0; i < inHeight; i++)
                for (var k = 0; k < inWidth; k++) {
                    tempInputArray[i + 1][k + 1] = inImageArray[i][k];
                }
            // 임시 출력 배열
            tempOutputArray = new Array(outHeight); //
            for (var i = 0; i < outHeight; i++)
                tempOutputArray[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    var S = 0.0;
                    for (var m = 0; m < 3; m++) {
                        for (var n = 0; n < 3; n++) {
                            S += 100 * mask[m][n] * tempInputArray[i + m][k + n].charCodeAt(0);
                        }
                    }
                    tempOutputArray[i][k] = S;
                }
            }
            // 만약, 마스크의 합계가 0이면, 결과를 127 더하자.
            // for(var i=0; i<outHeight; i++) 
            //     for (var k=0; k<outWidth; k++) 
            //         tempOutputArray[i][k] += 127.0;

            // 임시 출력 --> 진짜 출력 배열
            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    var v = tempOutputArray[i][k];
                    if (v > 255.0)
                        v = 255.0;
                    if (v < 0)
                        v = 0.0;
                    outImageArray[i][k] = String.fromCharCode(v);
                }
            displayImage();
        }
        function juImage() {  // 블러링 알고리즘
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            //// 화소 영역 처리
            var mask = [[1. / 9., 1. / 9., 1. / 9.], [1. / 9., 1. / 9., 1. / 9.], [1. / 9., 1. / 9., 1. / 9.]];
            // 임시 입력 배열
            tempInputArray = new Array(inHeight + 2); // 2칸 큼
            for (var i = 0; i < inHeight + 2; i++)
                tempInputArray[i] = new Array(inWidth + 2);
            // 임시 입력 배열 초기화
            for (var i = 0; i < inHeight + 2; i++)
                for (var k = 0; k < inWidth + 2; k++)
                    tempInputArray[i][k] = String.fromCharCode(127);
            // 입력 배열 --> 임시 입력
            for (var i = 0; i < inHeight; i++)
                for (var k = 0; k < inWidth; k++) {
                    tempInputArray[i + 1][k + 1] = inImageArray[i][k];
                }
            // 임시 출력 배열
            tempOutputArray = new Array(outHeight); //
            for (var i = 0; i < outHeight; i++)
                tempOutputArray[i] = new Array(outWidth);
            // 임시 출력 --> 진짜 출력 배열
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    var S = 0.0;
                    for (var m = 0; m < 3; m++) {
                        for (var n = 0; n < 3; n++) {
                            S += mask[m][n] * tempInputArray[i + m][k + n].charCodeAt(0);
                        }
                    }
                    tempOutputArray[i][k] = S;
                }
            }
            // 만약, 마스크의 합계가 0이면, 결과를 127 더하자.
            // for(var i=0; i<outHeight; i++) 
            //     for (var k=0; k<outWidth; k++) 
            //         tempOutputArray[i][k] += 127.0;

            // 임시 출력 --> 진짜 출력 배열
            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    var v = tempOutputArray[i][k];
                    if (v > 255.0)
                        v = 255.0;
                    if (v < 0)
                        v = 0.0;
                    outImageArray[i][k] = String.fromCharCode(v); 1
                }
            displayImage();
        }
        function lapImage() {  // 블러링 알고리즘
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for (var i = 0; i < outHeight; i++)
                outImageArray[i] = new Array(outWidth);

            //// 화소 영역 처리
            var mask = [[0., 1., 0.], [1., -4., 1.], [0., 1., 0.]];
            // 임시 입력 배열
            tempInputArray = new Array(inHeight + 2); // 2칸 큼
            for (var i = 0; i < inHeight + 2; i++)
                tempInputArray[i] = new Array(inWidth + 2);
            // 임시 입력 배열 초기화
            for (var i = 0; i < inHeight + 2; i++)
                for (var k = 0; k < inWidth + 2; k++)
                    tempInputArray[i][k] = String.fromCharCode(127);
            // 입력 배열 --> 임시 입력
            for (var i = 0; i < inHeight; i++)
                for (var k = 0; k < inWidth; k++) {
                    tempInputArray[i + 1][k + 1] = inImageArray[i][k];
                }
            // 임시 출력 배열
            tempOutputArray = new Array(outHeight); //
            for (var i = 0; i < outHeight; i++)
                tempOutputArray[i] = new Array(outWidth);

            // ***** 진짜 영상처리 알고리즘 *****
            for (var i = 0; i < inHeight; i++) {
                for (var k = 0; k < inWidth; k++) {
                    var S = 0.0;
                    for (var m = 0; m < 3; m++) {
                        for (var n = 0; n < 3; n++) {
                            S += mask[m][n] * tempInputArray[i + m][k + n].charCodeAt(0);
                        }
                    }
                    tempOutputArray[i][k] = S;
                }
            }
            // 만약, 마스크의 합계가 0이면, 결과를 127 더하자.
            // for(var i=0; i<outHeight; i++) 
            //     for (var k=0; k<outWidth; k++) 
            //         tempOutputArray[i][k] += 127.0;

            // 임시 출력 --> 진짜 출력 배열
            for (var i = 0; i < outHeight; i++)
                for (var k = 0; k < outWidth; k++) {
                    var v = tempOutputArray[i][k];
                    if (v > 255.0)
                        v = 255.0;
                    if (v < 0)
                        v = 0.0;
                    outImageArray[i][k] = String.fromCharCode(v);
                }
            displayImage();
        }
    </script>
</head>

<body onload='init()'>
    <h1>
        <div class="wordArtEffectText">PHOTO@@</div>
    </h1>
    <hr>
    <form>
        <input style="border: 5px groove rgb(255, 0, 0);" type='file' id='selectFile' onchange='openImage()' />
        <br>
        <label p style="border: 5px groove rgb(255, 153, 0)">화소점 처리</label>
        <select name='imageAlgo' onchange="ImageProcessing(this.form.imageAlgo)"
            style="border: 7px groove rgb(238, 255, 0);">
            <option value=0>선택 하세요 </option>
            <option value="1">동일 영상 처리</option>
            <option value="2">영상 밝게 하기</option>
            <option value="4">흑백 처리</option>
            <option value="5">흑백 처리(평균)</option>
            <option value="6">반대의 색</option>
        </select>
        <label p style="border: 5px groove rgb(0, 255, 21)">기하학 처리</label>
        <select name='imageAlgo1' onchange="ImageProcessing1(this.form.imageAlgo1)"
            style="border: 7px groove rgb(0, 17, 255);">
            <option value="20">선택 하세요 </option>
            <option value="21">축소 하기</option>
            <option value="22">확대 하기</option>
        </select>
        <br>
        <label p style="border: 5px groove rgb(47, 0, 255)">히스토그램</label>
        <select name='imageAlgo2' onchange="ImageProcessing2(this.form.imageAlgo2)"
            style="border: 7px groove rgb(140, 0, 255);">
            <option value="40">선택 하세요 </option>
            <option value="41">히스토그램 스트래칭</option>
            <option value="42">엔드-인 탐색</option>
            <option value="43">평활화 </option>
            <option value="44">히스토그램 차트 </option>
        </select>
        <br>
        <label p style="border: 5px groove rgb(0, 255, 234)">화소 영역처리</label>
        <select name='imageAlgo3' onchange="ImageProcessing3(this.form.imageAlgo3)"
            style="border: 7px groove rgb(255, 0, 170);">
            <option value="60"> 선택 하세요 </option>
            <option value="61"> 엠보싱 </option>
            <option value="62"> 블러링 </option>
            <option value="63"> 샤프닝 </option>
            <option value="64"> 가우시안 필터 </option>
            <option value="65"> 경계선 처리 </option>
            <option value="66"> 고주파 필터 </option>
            <option value="67"> 저주파 필터 </option>
            <option value="68"> 라플라시안 </option>
        </select>

        <br>
        <canvas id='outCanvas' style='background-color:rgb(164, 248, 192)'></canvas>
    </form>
</body>

</html>

'HTML5+ CSS3+ Javascript' 카테고리의 다른 글

8일차  (0) 2021.03.26
7일차  (0) 2021.03.26
5일차  (0) 2021.03.22
4일차  (0) 2021.03.19
3일차  (0) 2021.03.18