HTML5+ CSS3+ Javascript

4일차

구자룡 2021. 3. 19. 16:51

<!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>Document</title>
    <style>
        div {
            font: normal 24px verdana;
        }
        .wordArtEffectText {
            color: pink;
            text-shadow: 3px 3px skyblue;
        }
    </style>
    <script>
        // 전역 변수(*중요*)
        var inCanvas, inCtx, outCanvas, outCtx;  // 입력 캔버스 관련
        var inFile, inImageArray, outImageArray;  // 입력 파일 및 배열
        var inWidth, inHeight, outWidth, outHeight;  // 입력 영상의 폭과 높이
        var inPaper, outPaper; // 캔버스에는 한점한점이 안찍힘. 대신 캔버스에 종이를 붙임.
        function init() {
            inCanvas = document.getElementById('inCanvas');
            inCtx = inCanvas.getContext('2d');
            outCanvas = document.getElementById('outCanvas');
            outCtx = outCanvas.getContext('2d');
        }

        function readRawImage() {
            inFile = document.getElementById('selectFile').files[0];
            // 중요! 코드 (영상의 크기를 파악)
            inWidth = inHeight = Math.sqrt(inFile.size);
            // 입력 2차원 배열을 준비
            inImageArray = new Array(inHeight); // 256짜리 1차원 배열
            for(var i=0; i<inHeight; i++) 
                inImageArray[i] = new Array(inWidth);
            // 캔버스 크기를 결정
            inCanvas.width = inWidth;
            inCanvas.height = inHeight;
            // 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++) {
                        // 0,0  0,1  0,2 ...... 0,255
                        // 1,0  1,1, 1,2 .......1,255
                        // ....
                        // 255,0  255,1 ....... 255,255
                        var sPixel = (i * inHeight + k);
                        var ePixel = (i * inHeight + k) + 1;
                        inImageArray[i][k] = bin.slice(sPixel,ePixel); // 1개픽셀-->배열
                    }
                }
                // 화면에 출력하기 (사람용)
                inPaper = inCtx.createImageData(inHeight, inWidth); //종이 붙였음.
                for(var i=0; i<inHeight; i++) {
                    for (var k=0; k<inWidth; k++) {
                        var charValue = inImageArray[i][k].charCodeAt(0); // 깨진문자를 숫자로.
                        inPaper.data[(i*inWidth + k) * 4 + 0] = charValue; // R
                        inPaper.data[(i*inWidth + k) * 4 + 1] = charValue; // G
                        inPaper.data[(i*inWidth + k) * 4 + 2] = charValue; // B
                        inPaper.data[(i*inWidth + k) * 4 + 3] = 255; // Alpha
                    }
                }
                inCtx.putImageData(inPaper,0,0);

            }

        }        
///////  영상 처리 함수 모음 //////////
        function printOutImage() {
              // 캔버스 크기를 결정
            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 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);
                }
            }
          printOutImage();
        }
        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);
                }
            }
          printOutImage();
        }

        function bwAvgImage() {  // 흑백 알고리즘(평균값)
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            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);
                }
            }
          printOutImage();
        }
        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];
                }
            }
          printOutImage();
        }
        function zoomInImage() {
            // (중요!) 출력 영상의 크기를 결정... 알고리즘에 따름.
            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<outHeight; i++) {
                for (var k=0; k<outWidth; k++) {
                    // **** 요기가 핵심 알고리즘. (영상 확대)
                    outImageArray[i][k] = inImageArray[parseInt(i/scale)][parseInt(k/scale)];                  
                }
            }
          printOutImage();
        }
        function rlImage() {
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for(var i=0; i<outHeight; i++) 
                outImageArray[i] = new Array(outWidth);
            var aaa;
            for(var i=0; i<inHeight; i++) {
                for(var k=0;k<inWidth/2;k++) {
                    aaa = inImageArray[i][k];
                    inImageArray[i][k] = inImageArray[i][inWidth-k-1];
                    inImageArray[i][inWidth-k-1] = aaa;

                    //문자를 숫자로 바꿈
                }
            }
            for(var i=0; i<inHeight; i++) {
                for(var k=0;k<inWidth;k++) {
                    outImageArray[i][k] =inImageArray[i][k];
                }
            }
            printOutImage();
            }

        
        function udImage() {
            outHeight = inHeight;
            outWidth = inWidth;
            // 출력 2차원 배열을 준비
            outImageArray = new Array(outHeight); // 256짜리 1차원 배열
            for(var i=0; i<outHeight; i++) 
                outImageArray[i] = new Array(outWidth);
            var bbb;     
            for(var i=0; i<inHeight/2; i++) {
                for(var k=0;k<inWidth;k++) {
                    bbb = inImageArray[i][k];
                    inImageArray[i][k] = inImageArray[inHeight-i-1][k];
                    inImageArray[inHeight-i-1][k] = bbb;

                    //문자를 숫자로 바꿈
                }
            }
            for(var i=0; i<inHeight; i++) {
                for(var k=0;k<inWidth;k++) {
                    outImageArray[i][k] =inImageArray[i][k];
                }
            }            
            printOutImage();
        }
        function ucImage() {
            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<inHeight;k++) {
                    //문자를 숫자로 바꿈
                    pixel = inImageArray[i][k].charCodeAt(0);
                    //(색변환)
                    pixel = 255-pixel;
                    inImageArray[i][k] = String.fromCharCode(pixel);
                }
            }   
            for(var i=0; i<inHeight; i++) {
                for(var k=0;k<inWidth;k++) {
                    outImageArray[i][k] =inImageArray[i][k];
                }
            }                    
            printOutImage();
        }
    </script>
</head>
<body onload='init()'>
    <h2><div class="wordArtEffectText">호날두</div></h2>
    <hr>
    <dl>
        <dt><strong>사진선택</strong></dt>
    <input type='file' id='selectFile' onchange='readRawImage()'/>
    <br>
    <dt><strong>화소점 처리</strong></dt>
    <input type='button' id='photoAdd' value='밝게하기' onclick='addImage()'/>
    <input type='button' id='photoBW' value='흑백처리' onclick='bwImage()'/>
    <input type='button' id='photoAvgBW' value='흑백처리(평균)' onclick='bwAvgImage()'/>
    <input type='button' id='photoZoomUc' value='반대색' onclick='ucImage()'/><br>
    <dt><strong>기하학 처리</strong></dt>
    <input type='button' id='photoZoomOut' value='축소' onclick='zoomOutImage()'/>
    <input type='button' id='photoZoomIn' value='확대' onclick='zoomInImage()'/>
    <input type='button' id='photoZoomRl' value='좌/우' onclick='rlImage()'/>
    <input type='button' id='photoZoomUd' value='상/하' onclick='udImage()'/><br>   
    </dl>
    <br>
    <canvas id='inCanvas' style='background-color:rgb(248, 209, 164)'></canvas>
    <canvas id='outCanvas' style='background-color:rgb(164, 248, 192)'></canvas>


</body>
</html>

 

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

6일차  (0) 2021.03.23
5일차  (0) 2021.03.22
3일차  (0) 2021.03.18
2일차  (0) 2021.03.17
1일차  (0) 2021.03.16