본문 바로가기
  • Welcome J-Kyu Tstory
국비교육과정/javascript

[컬러영상처리]09-04 Color Image Processing(Alpha) Ver 0.1.html

by regularity 2022. 5. 17.
728x90

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
    // ---------------------------전역 변수부--------------------------------
    var inCanvas, outCanvas, inCtx, outCtx, inPaper, outPaper;  // 화면 관련 변수
    var inFile; // 칼라 파일(PNG, JPG, BMP)
    var inImage, outImage; // 입출력용 이미지 (3차원 배열)  --> 제일 중요
    var inH, inW, outH, outW; // 영상의 높이와 폭
</script>
<script>
    // -------------------------------공통 함수부--------------------------
    function init() {
        inCanvas = document.getElementById('inCanvas'); // 도화지에 접근
        outCanvas = document.getElementById('outCanvas'); // 도화지에 접근
        inCtx = inCanvas.getContext('2d'); // 물감,붓이 들은 통
        outCtx = outCanvas.getContext('2d'); // 물감,붓이 들은 통
    }
    function openImage() {
        // inFile = document.getElementById("inFile").files[0]; // 선택한 파일 "c:/html/picture01.png"
        var fileNum = document.getElementById('fileNum').value;
        if ( parseInt(fileNum) < 9)
            fileNum = "0" + fileNum;
        else
            fileNum = fileNum;
        var inFname = "Nature99(Small)/picture" + fileNum + ".jpg";
        // 그림 파일 --> 이미지 객체
        var inPicture = new Image();  // 빈 이미지 객체
        inPicture.src = inFname;
        inPicture.onload = function() {
            // 중요! 입력 영상의 크기를 알아내기
            inH = inPicture.height;
            inW = inPicture.width;
            // 캔버스 크기 조절
            inCanvas.height = inH;
            inCanvas.width = inW;
            inCtx.drawImage(inPicture,0,0,inW,inH); //컬러사진을 그대로 출력시켜줌
            // 메모리 할당 (3차원 배열)
            inImage = new Array(3); // 3면
            for(var m=0; m<3; m++) {
                inImage[m] = new Array(inH);
                for(var i=0; i<inH; i++)
                    inImage[m][i] = new Array(inW);
            }
            // *중요* 캔버스의 이미지(화면) --> 배열로 칼라 추출
            var colorBlob = inCtx.getImageData(0,0,inW,inH); 
            var R, G, B, Alpha;
            for(var i=0; i<inH; i++) {
                for (var k=0; k<inW; k++) {
                    var pos = (i*inW + k) * 4; // 1픽셀 = 4byte
                    R = colorBlob.data[pos+0]; // Red
                    G = colorBlob.data[pos+1]; // Green
                    B = colorBlob.data[pos+2]; // Blue
                    // Alpha = colorBlob.data[pos+3]; // Alpha
                    inImage[0][i][k] = R;
                    inImage[1][i][k] = G;
                    inImage[2][i][k] = B;                    
                }
            }


        }
    }
    
    function display() {
        // 출력 메모리를 페이퍼에 출력하고, 페이퍼를 캔버스에 붙이기
        outPaper = outCtx.createImageData(outW, outH); // 그림크기의 빈 종이를 준비
        // 캔버스 크기
            outCanvas.height = outH;
            outCanvas.width = outW;
            // 종이에 콕콕콕 찍기
            for(var i=0; i<outH; i++) {
                for (var k=0; k<outW; k++) {
                    var R = outImage[0][i][k]; // 0~255 사이의 값
                    var G = outImage[1][i][k]; // 0~255 사이의 값
                    var B = outImage[2][i][k]; // 0~255 사이의 값
                    outPaper.data[ (i*outW + k)*4 + 0] = R; // Red
                    outPaper.data[ (i*outW + k)*4 + 1] = G; // Green
                    outPaper.data[ (i*outW + k)*4 + 2] = B; // Blue
                    outPaper.data[ (i*outW + k)*4 + 3] = 255; // Alpha
                }
            }
            outCtx.putImageData(outPaper, 0, 0); // 종이를 캔버스에 붙이기.
        }

        function setSize(){
            // 중요! 출력 영상 크기 결정 ---> 알고리즘에 의존
            outH = inH;
            outW = inW;
            // 메모리 할당 (3차원 배열)
            outImage = new Array(3); // 3면
            for(var m=0; m<3; m++) {
                outImage[m] = new Array(outH);
                for(var i=0; i<outH; i++)
                    outImage[m][i] = new Array(outW);
            }
        }
    // -------------------------------공통 함수부 끝--------------------------
</script>

<script>
    // ---------------------------------영상처리 알고리즘---------------------------------
    //======================== 기능 선택=======================
    function selectAlgorithm(selectNum) {
        switch(parseInt(selectNum.value)) {
            //화소점
            case 101 : // 동일영상
                equalImage();
                break;
            case 102 : // 밝게하기
                brightImage();
                break;
            case 103 : // 그레이스케일
                grayImage();
                break;
            case 104 : // 흑백 영상
                bwImage();
                break;
            case 105 : // 영상반전
                reverseImage();
                break;

     
           
            //기하학
            case 201 : // 영상 90도 오른쪽
                rotateR();
                break;
            case 202 : // 영상 90도 왼쪽
                rotateL();
                break;
            case 203 : // 영상좌우반전
                reverseVImage();
                break;
            case 204 : // 영상상하반전
                reverseHImage();
                break;
            case 205 : // 영상축소
                zoomOutImage();
                break;
            case 206 : // 영상확대
                zoomInImage();
                break;




            //화소영역(마우스)
            case 501 : // 흑백 처리(마우스)
                bwImage_mouse();
                break;
            case 502 : // 밝기 처리(마우스)
                addImage_mouse();
                break;
            case 503 : // 그레이스케일 처리(마우스)
                grayScaleImage_mouse();
                break;
        }
    }
    //======================================화소점========================================
    //==================동일 영상=================
    function equalImage() { //case 101
        // 중요! 출력 영상 크기 결정 ---> 알고리즘에 의존
        outH = inH;
        outW = inW;
        // 메모리 할당 (3차원 배열)
        //outImage = new Integer[3][outH][outW]; //C 제외하고
        outImage = new Array(3); // 3면
        for(var m=0; m<3; m++) {
            outImage[m] = new Array(outH);
            for(var i=0; i<outH; i++)
                outImage[m][i] = new Array(outW);
        }
        // ** 진짜 영상처리 알고리즘 **
        for (var rgb=0; rgb < 3; rgb++) {
            for (var i=0; i<inH; i++) {
                for (var k=0; k<inW; k++) {
                    outImage[rgb][i][k] = inImage[rgb][i][k];
                }
            }
        }
        display();
    }

    //==================밝기 조절=================
    function brightImage() {    //case 102
        setSize();
        // ** 진짜 영상처리 알고리즘 **
        var value=parseInt(prompt("숫자:", "100"));
        for (var rgb=0; rgb < 3; rgb++) {
            for (var i=0; i<inH; i++) {
                for (var k=0; k<inW; k++) {
                    if (inImage[rgb][i][k] + 100 > 255)
                        outImage[rgb][i][k] = 255;
                    else
                        outImage[rgb][i][k] = inImage[rgb][i][k] + 100;
                }
            }
        }
        display();
    }

    //==================그레이스케일=================
    function grayImage() {  //case 103
        setSize();
        // ** 진짜 영상처리 알고리즘 **
        for (var i=0; i<inH; i++) {
            for (var k=0; k<inW; k++) {
                var hap = inImage[0][i][k] + inImage[1][i][k] + inImage[2][i][k];
                var avg = parseInt(hap / 3);

                outImage[0][i][k] = outImage[1][i][k] = outImage[2][i][k] = avg;
            }
        }

        display();
    }

    //==================흑백 영상=================
    function bwImage() { //case 104
        // 중요! 출력 영상 크기 결정 ---> 알고리즘에 의존
        outH = inH;
        outW = inW;
        // 메모리 할당 (3차원 배열)
        //outImage = new Integer[3][outH][outW]; //C 제외하고
        outImage = new Array(3); // 3면
        for(var m=0; m<3; m++) {
            outImage[m] = new Array(outH);
            for(var i=0; i<outH; i++)
                outImage[m][i] = new Array(outW);
        }
        // ** 진짜 영상처리 알고리즘 **
        for (var rgb=0; rgb < 3; rgb++) {
            for (var i=0; i<inH; i++) {
                for (var k=0; k<inW; k++) {
                    var hap = inImage[0][i][k] + inImage[1][i][k] + inImage[2][i][k];   //그레이스케일로 먼저 바꾼뒤 처리해줘야 하기 때문에
                    var avg = parseInt(hap / 3);
                   
                    if(avg > 127)
                        outImage[rgb][i][k] =255;
                    else
                        outImage[rgb][i][k] = 0;
                }
            }
        }
        display();
    }

    //==================영상 반전=================
    function reverseImage() {   //case 105
        setSize();
        
        // ** 진짜 영상처리 알고리즘 **
        for (var rgb=0; rgb < 3; rgb++) {
            for (var i=0; i<inH; i++) {
                for (var k=0; k<inW; k++) {
                      //******핵심 알고리즘(영상 축소)
                      outImage[rgb][i][k]  = 255-inImage[rgb][i][k];
                }
            }

        display();
        }
    }  

//======================================기하학========================================
//==================영상 90도 오른쪽=================
    function  rotateR() { //case 201
         //출력 영상 크기
        outH = inW;
        outW = inH;
        //영상 크기 메모리 확보(3차원)
        outImage = new Array(3) ; 
        for(var m=0; m<3; m++){
            outImage[m] = new Array(outH);
            for(var i=0; i<outH; i++)
                outImage[m][i] = new Array(outW);
        }
        // ** 진짜 영상처리 알고리즘 **
        for (var rgb=0; rgb < 3; rgb++) {
            for (var i=0; i<inH; i++) {
                for (var k=0; k<inW; k++) {
                    outImage[rgb][k][(inH-i-1)] = inImage[rgb][i][k];
                }
            }
        }
        display();
    }

//==================영상 90도 왼쪽=================
    function  rotateL() { //case 202
        outH = inW;
        outW = inH;
        //영상 크기 메모리 확보(3차원)
        outImage = new Array(3) ; 
        for(var m=0; m<3; m++){
            outImage[m] = new Array(outH);
            for(var i=0; i<outH; i++)
                outImage[m][i] = new Array(outW);
        }
        // ** 진짜 영상처리 알고리즘 **
        for (var rgb=0; rgb < 3; rgb++) {
            for (var i=0; i<inH; i++) {
                for (var k=0; k<inW; k++) {
                    outImage[rgb][inW-k-1][i] = inImage[rgb][i][k];
                }
            }
        }
        display();
    }

 //==================영상 좌우 반전=================
 function reverseVImage() {   //case 203
        setSize();
        // ** 진짜 영상처리 알고리즘 **
        for (var rgb=0; rgb < 3; rgb++) {
            for (var i=0; i<inH; i++) {
                for (var k=0; k<inW; k++) {
                  outImage[rgb][i][k] = inImage[rgb][i][inW-k-1];
                }
            }
       
        display();
        }
    }
    //==================영상 상하 반전=================
    function reverseHImage() {   //case 204
        setSize();
        // ** 진짜 영상처리 알고리즘 **
        for (var rgb=0; rgb < 3; rgb++) {
            for (var i=0; i<inH; i++) {
                for (var k=0; k<inW; k++) {
                  outImage[rgb][i][k] = inImage[rgb][inH-i-1][k];
                }
            }
       
        display();
        }
    }
    //==================영상 축소=================
    function zoomOutImage() {   //case 205
        //배율 입력
        var scale = parseInt(prompt("배율", "2"));
        //출력 영상 크기
        outH = inH / scale;
        outW = inW / scale;
        //영상 크기 메모리 확보(3차원)
        outImage = new Array(3) ; 
        for(var m=0; m<3; m++){
            outImage[m] = new Array(outH);
            for(var i=0; i<outH; i++)
                outImage[m][i] = new Array(outW);
        }
        // ** 진짜 영상처리 알고리즘 **
        for (var rgb=0; rgb < 3; rgb++) {
            for (var i=0; i<inH; i++) {
                for (var k=0; k<inW; k++) {
                      //******핵심 알고리즘(영상 축소)
                      outImage[rgb][parseInt(i/scale)][parseInt(k/scale)]  = inImage[rgb][i][k];
                }
            }

        display();
        }
    }
    //==================영상 확대=================
    function zoomInImage() {   //case 206
        //배율 입력
        var scale = parseInt(prompt("확대배율(짝수)", "2"));
        //출력 영상 크기
        outH = inH * scale;
        outW = inW * scale;
        //영상 크기 메모리 확보(3차원)
        outImage = new Array(3) ; 
        for(var m=0; m<3; m++){
            outImage[m] = new Array(outH);
            for(var i=0; i<outH; i++)
                outImage[m][i] = new Array(outW);
        }
        // ** 진짜 영상처리 알고리즘 **
        for (var rgb=0; rgb < 3; rgb++) {
            for (var i=0; i<outH; i++) {
                for (var k=0; k<outW; k++) {
                      //******핵심 알고리즘(영상 축소)
                      //outImage[rgb][parseInt(i*scale)][parseInt(k*scale)]  = inImage[rgb][i][k];
                      outImage[rgb][i][k]  = inImage[rgb][parseInt(i/scale)][parseInt(k/scale)];
                }
            }

        display();
        }
    }

    


//======================================선택영역(사각형) 영상처리========================================

//---------------------흑백처리(사각형)-----------------------
function bwImage() {  //CASE : 501
        // 중요! 출력 영상 크기 결정 ---> 알고리즘에 의존
        outH = inH;
        outW = inW;
        // 메모리 할당 (3차원 배열)
        // outImage = new Integer[3][outH][outW]; // C제외하고 나머지 언어.
        outImage = new Array(3); // 3면
        for(var m=0; m<3; m++) {
            outImage[m] = new Array(outH);
            for(var i=0; i<outH; i++)
                outImage[m][i] = new Array(outW);
        }
        // ** 진짜 영상처리 알고리즘 **
        for (var rgb=0; rgb < 3; rgb++) {
            for (var i=0; i<inH; i++) {
                for (var k=0; k<inW; k++) {
                    var hap = inImage[0][i][k] + inImage[1][i][k] + inImage[2][i][k];
                    var avg = parseInt(hap / 3);

                    if (avg > 127)
                        outImage[rgb][i][k] = 255;
                    else 
                        outImage[rgb][i][k] = 0;
                }
            }
        }
        display();
    }

    var pressYN = false;
    var startX, startY, endX, endY;
    var imageData;
    function bwImage_mouse() {
        inCanvas.addEventListener("mousedown", __downMouse, false);
        inCanvas.addEventListener("mouseup", __upMouse, false);
        inCanvas.addEventListener("mousemove", __moveMouse, false);

        function __downMouse(event) {  // 콜백 함수(Call Back)
            startX = event.offsetX;
            startY = event.offsetY;  
            imageData = inCtx.getImageData(0,0,inCanvas.width,inCanvas.height);   
            pressYN = true;   
        }

        function __moveMouse(event) {
            if (!pressYN)
                return;
            
            inCtx.putImageData(imageData, 0, 0);

            endX = event.offsetX;
            endY = event.offsetY;
            inCtx.beginPath(); // 선 그리기 시작
            inCtx.strokeStyle='blue'; // 선 색상
            inCtx.lineWidth = 1; // 선 두께
            inCtx.rect(startX,startY, (endX-startX), (endY-startY))
            obj = inCtx.stroke();
            inCtx.closePath(); // 선 그리기 끝
        }

        function __upMouse(event) {
            pressYN = false;
            endX = event.offsetX;
            endY = event.offsetY;

            // 좌우/상하 박스 좌표가 필요
            if(startX > endX) {
                temp = startX;
                startX = endX;
                endX = temp;
            }
            if(startY > endY) {
                temp = startY;
                startY = endY;
                endY = temp;
            }
            inCanvas.removeEventListener("mousedown", __downMouse, false);
            inCanvas.removeEventListener("mouseup", __upMouse, false);
            inCanvas.removeEventListener("mousemove", __moveMouse, false);    
            __bwImage();
        } // function __upMouse(event)

     

        function __bwImage() {  //case : 501 흑백 처리(마우스)
            // 중요! 출력 영상 크기 결정 ---> 알고리즘에 의존
            outH = inH;
            outW = inW;
            // 메모리 할당 (3차원 배열)
            // outImage = new Integer[3][outH][outW]; // C제외하고 나머지 언어.
            outImage = new Array(3); // 3면
            for(var m=0; m<3; m++) {
                outImage[m] = new Array(outH);
                for(var i=0; i<outH; i++)
                    outImage[m][i] = new Array(outW);
            }
            // ** 진짜 영상처리 알고리즘 **
            for (var rgb=0; rgb < 3; rgb++) {
                for (var i=0; i<inH; i++) {
                    for (var k=0; k<inW; k++) {

                        if ( (startX <= k && k <= endX  ) && (startY <= i && i <= endY)) {
                            var hap = inImage[0][i][k] + inImage[1][i][k] + inImage[2][i][k];
                            var avg = parseInt(hap / 3);
                            if (avg > 127)
                                outImage[rgb][i][k] = 255;
                            else 
                                outImage[rgb][i][k] = 0;
                        } else {
                            outImage[rgb][i][k] = inImage[rgb][i][k]
                        }
                        
                        // 아니면 그냥 원래 값


                    }
                }
            }
            display();
        } //function __bwImage() {

        

    }  // function bwImage_mouse()



    //---------------------밝기처리(사각형)-----------------------
    function addImage_mouse() { //CASE : 502
            inCanvas.addEventListener("mousedown", __downMouse, false);
            inCanvas.addEventListener("mouseup", __upMouse, false);
            inCanvas.addEventListener("mousemove", __moveMouse, false);

            function __downMouse(event) {  // 콜백 함수(Call Back)
                startX = event.offsetX;
                startY = event.offsetY;
                imageData = inCtx.getImageData(0, 0, inCanvas.width, inCanvas.height);
                pressYN = true;
            }

            function __moveMouse(event) {
                if (!pressYN)
                    return;

                inCtx.putImageData(imageData, 0, 0);

                endX = event.offsetX;
                endY = event.offsetY;
                inCtx.beginPath(); // 선 그리기 시작
                inCtx.strokeStyle = 'white'; // 선 색상
                inCtx.lineWidth = 1; // 선 두께
                inCtx.rect(startX, startY, (endX - startX), (endY - startY))
                obj = inCtx.stroke();
                inCtx.closePath(); // 선 그리기 끝
            }

            function __upMouse(event) {
                pressYN = false;
                endX = event.offsetX;
                endY = event.offsetY;

                // 좌우/상하 박스 좌표가 필요
                if (startX > endX) {
                    temp = startX;
                    startX = endX;
                    endX = temp;
                }
                if (startY > endY) {
                    temp = startY;
                    startY = endY;
                    endY = temp;
                }
                inCanvas.removeEventListener("mousedown", __downMouse, false);
                inCanvas.removeEventListener("mouseup", __upMouse, false);
                inCanvas.removeEventListener("mousemove", __moveMouse, false);
                __addImage();
            } // function __upMouse(event)



            function __addImage() {
                // 중요! 출력 영상 크기 결정 ---> 알고리즘에 의존
                outH = inH;
                outW = inW;
                // 메모리 할당 (3차원 배열)
                // outImage = new Integer[3][outH][outW]; // C제외하고 나머지 언어.
                outImage = new Array(3); // 3면
                for (var m = 0; m < 3; m++) {
                    outImage[m] = new Array(outH);
                    for (var i = 0; i < outH; i++)
                        outImage[m][i] = new Array(outW);
                }
                // ** 진짜 영상처리 알고리즘 **
                for (var rgb = 0; rgb < 3; rgb++) {
                    for (var i = 0; i < inH; i++) {
                        for (var k = 0; k < inW; k++) {
                            if ((startX <= k && k <= endX) && (startY <= i && i <= endY)) {
                                outImage[rgb][i][k] = inImage[rgb][i][k] + 100;
                            }
                            else {
                            outImage[rgb][i][k] = inImage[rgb][i][k];
                            }
                            
                        }
                    }
                    display();
                }
           }
        }
    
        //----------------------그레이스케일(사각형)----------------------
        function grayScaleImage_mouse(){ // CASE :503
            inCanvas.addEventListener("mousedown", __downMouse, false);
            inCanvas.addEventListener("mouseup", __upMouse, false);
            inCanvas.addEventListener("mousemove", __moveMouse, false);

            function __downMouse(event) {  // 콜백 함수(Call Back)
                startX = event.offsetX;
                startY = event.offsetY;
                imageData = inCtx.getImageData(0, 0, inCanvas.width, inCanvas.height);
                pressYN = true;
            }

            function __moveMouse(event) {
                if (!pressYN)
                    return;

                inCtx.putImageData(imageData, 0, 0);

                endX = event.offsetX;
                endY = event.offsetY;
                inCtx.beginPath(); // 선 그리기 시작
                inCtx.strokeStyle = 'white'; // 선 색상
                inCtx.lineWidth = 1; // 선 두께
                inCtx.rect(startX, startY, (endX - startX), (endY - startY))
                obj = inCtx.stroke();
                inCtx.closePath(); // 선 그리기 끝
            }

            function __upMouse(event) {
                pressYN = false;
                endX = event.offsetX;
                endY = event.offsetY;

                // 좌우/상하 박스 좌표가 필요
                if (startX > endX) {
                    temp = startX;
                    startX = endX;
                    endX = temp;
                }
                if (startY > endY) {
                    temp = startY;
                    startY = endY;
                    endY = temp;
                }
                inCanvas.removeEventListener("mousedown", __downMouse, false);
                inCanvas.removeEventListener("mouseup", __upMouse, false);
                inCanvas.removeEventListener("mousemove", __moveMouse, false);
                __grayScaleImage();
            } // function __upMouse(event)



            function __grayScaleImage() {
                // 중요! 출력 영상 크기 결정 ---> 알고리즘에 의존
                outH = inH;
                outW = inW;
                // 메모리 할당 (3차원 배열)
                // outImage = new Integer[3][outH][outW]; // C제외하고 나머지 언어.
                outImage = new Array(3); // 3면
                for (var m = 0; m < 3; m++) {
                    outImage[m] = new Array(outH);
                    for (var i = 0; i < outH; i++)
                        outImage[m][i] = new Array(outW);
                }
                // ** 진짜 영상처리 알고리즘 **
                for (var rgb = 0; rgb < 3; rgb++) {
                    for (var i = 0; i < inH; i++) {
                        for (var k = 0; k < inW; k++) {
                            if ((startX <= k && k <= endX) && (startY <= i && i <= endY)) {
                                var hap = inImage[0][i][k] + inImage[1][i][k] + inImage[2][i][k];
                                var avg = parseInt(hap / 3);

                                outImage[0][i][k] = outImage[1][i][k] = outImage[2][i][k] = avg;
                            }
                            else {
                            outImage[rgb][i][k] = inImage[rgb][i][k]
                            }
                        }
                    }
                    display();
                }
           }
        }
   
    
</script>

<!-- ----------------------------------Body---------------------------------- -->
</head>
<body onload="init()">
    <h1> Color Image Processing (Alpha_04)</h1>
    <form>
            <input type="number" id="fileNum"/>
            <input type="button" id="inFile" value="이미지 열기" onclick="openImage()" /><br>
            <select name='pixel' onchange="selectAlgorithm(this.form.pixel)">
                <option value=0> 선택하세요(화소점) </option>
                <optgroup label = "화소점 처리">
                    <option value=101> 동일 영상 </option>
                    <option value=102> 밝게 하기 </option>
                    <option value=103> 그레이스케일 </option>
                    <option value=104> 흑백 영상 </option>
                    <option value=105> 영상 반전 </option>
                </optgroup>
            </select>
            <select name='geo' onchange="selectAlgorithm(this.form.geo)">    
                <option value=0> 선택하세요(기하학) </option>
                <optgroup label = "기하학 처리">
                    <option value=201> 90도 오른쪽 회전 </option>
                    <option value=202> 90도 왼쪽 회전 </option>
                    <option value=203> 영상 좌우반전 </option>
                    <option value=204> 영상 상하반전 </option>
                    <option value=205> 영상 축소 </option>                    
                    <option value=206> 영상 확대 </option>                    
                </optgroup>
            </select>            
  
            

            <select name='selectRect' onchange="selectAlgorithm(this.form.selectRect)"> 
                <option value=0> 선택하세요(화소점_마우스) </option>                               
                <optgroup label = "화소점 마우스">
                    <option value=501>  선택 영역 흑백 변환 </option>
                    <option value=502>  선택 영역 밝기 변환 </option>
                    <option value=503>  선택 영역 그레이스케일 변환 </option>
                </optgroup>       
            </select>   
                  
         </form>
        <br>
        <canvas id="inCanvas" style="background-color:aqua"></canvas>
        <canvas id="outCanvas" style="background-color:goldenrod"></canvas>
    </body>
</html>
728x90

댓글