[JavaScript] Canvas로 이미지 서버에 전송하기 - Sample[JavaScript] Canvas로 이미지 서버에 전송하기 - Sample

Posted at 2020. 3. 6. 17:38 | Posted in JavaScript & jQuery/JavaScript




참고 : https://bugsdb.com/_ko/debug/14292f07a628fd12f3b6afc4a751f956






■ 캔버스로 생성한 이미지 파일 서버에 업로드 하기




# 소스코드 - 클라이언트 페이지 ( 이미지 전송 )

 canvas_upload.php

<html>

<head>

<meta charset="UTF-8">

<title>:: JavaScript 캔버스 이미지 업로드 ::</title>

<meta name="viewport" content="width=device-width">

<link type="text/css" rel="stylesheet" href="./css/modern.css"/>

<style type="text/css">

    .imgArea { text-align:center; }

    canvas, #uploadFile, #submitBtn { display:none; }

</style>

<script type="text/javascript">


    // @breif AJAX 통신 함수

    function getXMLHTTPRequest() {

        let request = false;

        try { request = new XMLHttpRequest(); }

        catch(err01) {

            try { request = new ActiveXObject("Msxml2.XMLHTTP"); }

            catch(err02) {

                try { request = new ActiveXObject("Microsoft.XMLHTTP"); }

                catch(err03) { request = false; }

            }

        }

        return request;

    }


    const ajax = getXMLHTTPRequest();


    // @breif 이미지 업로드 함수

    function uploadImgFilePrinted() {


        // @details 업로드 파일 정보를 받아온다.

        let fileInfo = document.getElementById("uploadFile").files[0];

        let reader = new FileReader();


        reader.onload = function() {


            // @details 업로드 버튼 이미지의 넓이와 높이에 맞게 썸네일을 생성을 위해 그 값을 받아온다.

            const btnWidth = document.getElementById("uploadImg").width;

            const btnHeight = document.getElementById("uploadImg").height;


            // @details 업로드 이미지 출력

            document.getElementById("uploadImg").src = reader.result;

            document.getElementById("uploadImg").width = btnWidth;

            document.getElementById("uploadImg").height = btnHeight;


            // @details 등록버튼 노출

            document.querySelector("#submitBtn").style.display = "inline";

        };


        if(fileInfo) {

            // @details readAsDataURL을 통해 업로드한 파일의 URL을 읽어 들인다.

            reader.readAsDataURL(fileInfo);

        }

    }


    function registryUploadImg() {

        if(confirm("업로드한 이미지를 업로드 하시겠습니까?") == true) {


            let upImage = new Image();

            upImage.src = document.getElementById("uploadImg").src;


            upImage.onload = function() {


                // @breif 캔버스 위에 이미지 그리기

                let canvas = document.querySelector("canvas");

                let canvasContext = canvas.getContext("2d");


                // @details 리사이즈할 이미지의 크기는, 현재 클라이언트에게 노출되어 있는 이미지 크기로 지정

                const btnWidth = document.getElementById("uploadImg").width;

                const btnHeight = document.getElementById("uploadImg").height;


                // @details 캔버스 생성 및 이미지 그리기

                canvas.width = btnWidth;

                canvas.height = btnHeight;

                canvasContext.drawImage(this, 0, 0, btnWidth, btnHeight);


                // @details AJAX 전송 데이터 설정

                const arrData =  {

                      "mode" : "imgFileUpload"

                    , "imgBase64" : canvas.toDataURL("image/jpeg")

                    , "imgFileName" : document.getElementById("uploadFile").files[0]['name']

                };


                ajax.open("POST", "./upload_image.php", true); // @details 비동기 방식 사용

                ajax.setRequestHeader("Content-Type", "application/json;charset=UTF-8;");

                ajax.send(JSON.stringify(arrData));


                ajax.onreadystatechange = function() {

                    if(ajax.readyState == 4) {

                        if(ajax.status == 200) {

                            const json = JSON.parse(ajax.responseText);

                            if(json.ret == "success") {

                                alert(json.message);

        } else {

                                alert(json.message);

                            }

                        } else {

                            alert(json.message);

                        }

                    }

                };

            };


        } else {

            return false;

        }

    }

</script>

<link rel="import" href="/edit_img.html">

</head>

<body>

<div class="windowFilm"></div>

<form id="uploadFrom" method="post">

    <input type="file" id="uploadFile" onChange="uploadImgFilePrinted();" accept="image/*"/>

    <div class="contents">

        <h1>캔버스&nbsp;업로드<span>샘플</span></h1>

        <div class="imgArea">

            <a href="javascript:;" onClick="document.getElementById('uploadFile').click();">

                <img id="uploadImg" src="./user-anonymous.png"/>

            </a>

            <br/><br/>

            <input id="submitBtn" type="button" onClick="registryUploadImg();" value="등록">

        </div>

        <canvas></canvas>

        <div class="copyright" style="bottom:0;">

            <p>Producer &copy; 사악미소</p>

        </div>

    </div>

</form>

</body>

</html> 




# 소스코드 - 서버 ( 이미지 파일 저장 )

 upload_image.php

<?php

$RetVal = array("ret"=>"fail", "error"=>"", "error_msg"=>"", "message"=>"");

$backUrl = $_SERVER['HTTP_REFERER'];


// @breif php://input은 내용의 유형에 관계없이 요청 HTTP 헤더 뒤에 모든 원시 데이터를 반환한다.

$data = json_decode(file_get_contents("php://input"), true);


switch($data['mode']) {


    // @breif ajax 이미지 업로드

    case "imgFileUpload" :


        // @breif base64로 암호화된 이미지 파일명 디코드

        $uploadCanvas = base64_decode(preg_replace("#^data:image/\w+;base64,#i", "", $data['imgBase64']));


        // @breif 파일명과 확장자를 분리 하여 담는다.

        $fileName = array_shift(explode(".", $data['imgFileName'])); // @details 이미지 파일 이름


        // @breif 이미지 파일명 변경

        $uploadImgName = $fileName."_".time().".jpg";


        // @breif 업로드할 이미지 경로 설정

        $uploadSrc = "./upload/".$uploadImgName;


        // @breif 이미지 파일 저장

        file_put_contents($uploadSrc, $uploadCanvas);


        // @breif 성공 여부 확인

        if(file_exists($uploadSrc) == TRUE) {

            $RetVal['ret'] = "success";

            $RetVal['message'] = "파일을 업로드 하는데 성공하였습니다.\n축하합니다.";

        } else {

            $RetVal['message'] = "파일을 업로드 하는데 실패하였습니다.\n다시 시도하여 주시기 바랍니다.";

        }


// @return 업로드 성공 / 실패 유무를 json 방식으로 웹 페이지에 전달한다.

        print json_encode($RetVal);

        return;


    break;


    default :


    $RetVal['message'] = "서버와의 연결 실패";

    print json_encode($RetVal);

        return;


    break;

}


header("location:".$backUrl);

?>





# 출력결과







관련포스팅#01 : [JavaScript] 이미지 파일 썸네일 생성하기

관련포스팅#02 : [JavaScript] Canvas를 통한 이미지 회전

관련포스팅#03 : [JavaScript] Canvas로 이미지 서버에 전송하기 - Sample

관련포스팅#04 : [jQuery] JCROP을 이용한 이미지 자르기 - Sample










Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기

[jQuery] JCROP을 이용한 이미지 자르기 - Sample[jQuery] JCROP을 이용한 이미지 자르기 - Sample

Posted at 2020. 2. 11. 13:29 | Posted in JavaScript & jQuery/jQuery





Jcrop 다운 : http://deepliquid.com/content/Jcrop.html

Jcrop API : https://jcrop.com/

GitHub : https://github.com/tapmodo/Jcrop





■ JCROP을 이용한 업로드한 크롭( CROP ) 하기





웹 브라우저 상에서 이미지를 업로드하고, 해당 이미지를 편집 하는 기능을 제작하게 되었다.


HTML5의 캔버스를 통해 업로드한 이미지를 똑같이 복사하여, 작업영역을 만들고.


캔버스에서 작업이 완료된 그림을 다시 원본 이미지와 교체하는형태로 서버에 업로드 하지 않고 작업하는것을 마무리 하였다.




# 소스코드

<html>

<head>

<meta charset="UTF-8">

<title>:: JavaScript 캔버스 이미지 업로드 ::</title>

<meta name="viewport" content="width=device-width">

<link type="text/css" rel="stylesheet" href="./css/modern.css"/>

<link type="text/css" rel="stylesheet" href="http://jcrop-cdn.tapmodo.com/v0.9.12/css/jquery.Jcrop.min.css"/>

<style type="text/css">

    .imgArea { text-align:center; }

    canvas, #uploadFile, #editBtn, #cutBtn { display:none; }

    body { overflow:hidden };

</style>

<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>

<script type="text/javascript" src="http://jcrop-cdn.tapmodo.com/v0.9.12/js/jquery.Jcrop.min.js"></script>

<script type="text/javascript">

    let jcropApi = null;


    // @breif 이미지 크롭 영역지정 UI 나타내기

    function imgCropDesignate() {


        let editWidth = jQuery("#editImg").width();

        let editHeight = jQuery("#editImg").height();

       

        // @breif jcrop 실행시 크롭영역을 미리 세팅

        let x1 = window.screen.width / 2 - editWidth;

        let y1 = window.screen.height / 2 - editHeight;

        let x2 = editWidth / 1.5;

        let y2 = editHeight / 1.5;


        // @breif jcrop 실행

        jQuery("#editImg").Jcrop({

              bgFade : true

            , bgOpacity : .2

            , setSelect : [ x1, y1, x2, y2 ]

            , onSelect : updateCoords

        }, function() {

            jcropApi = this;

        });

        

        jQuery("#editBtn").css("display", "none");

        jQuery("#cutBtn").css("display", "inline");

    }

    

    // @breif 지정된 크롭 한 영역( 좌표, 넓이, 높이 )의 값을 보관하는 함수

    function updateCoords(crap) {

        jQuery("#xAxis").val(crap.x);

        jQuery("#yAxis").val(crap.y);

        jQuery("#wLength").val(crap.w);

        jQuery("#hLength").val(crap.h);

    }


    // @breif 크롭한 영역 잘라내고 추출하기

    function imgCropApply() {


        if(parseInt(jQuery("#wLength").val()) == "NaN") {

            alert("이미지를 크롭한 이후\n자르기 버튼을 클릭하세요.");

            return false;

        } else {


            let editImage = new Image();

            editImage.src = jQuery("#editImg").attr("src");


            editImage.onload = function() {


                // @breif 캔버스 위에 이미지 그리기

                let canvas = document.querySelector("canvas");

                let canvasContext = canvas.getContext("2d");


                // @breif 캔버스 크기를 이미지 크기와 동일하게 지정

                canvas.width = jQuery("#wLength").val();

                canvas.height = jQuery("#hLength").val();

                                

                canvasContext.drawImage(

                      this

                    , jQuery("#xAxis").val()        // 자르기를 시작할 x좌표

                    , jQuery("#yAxis").val()        // 자르기를 시작할 y좌표

                    , jQuery("#wLength").val()    // 잘라낸 이미지의 넓이

                    , jQuery("#hLength").val()    // 잘라낸 이미지의 높이

                    , 0                                         // 캔버스에 이미지를 배치할 x좌표

                    , 0                                         // 캔버스에 이미지를 배치할 y좌표

                    , jQuery("#wLength").val()    // 사용할 이미지의 넓이(이미지 스트레칭 또는 축소)

                    , jQuery("#hLength").val()    // 사용할 이미지의 높이(이미지 스트레칭 또는 축소)

                );


                // @breif 편집한 캔버스의 이미지를 화면에 출력한다.

                let dataURI = canvas.toDataURL("image/jpeg");

                jQuery("#editImg").attr("src", dataURI);

                

                // @breif 이미지의 크기는 자른 이미지와 동일하게 지정

                jQuery("#editImg").css("width", jQuery("#wLength").val());

                jQuery("#editImg").css("height", jQuery("#hLength").val());

            };


            jQuery("#cutBtn").css("display", "none");


            // @details JCROP을 종료한다.

            jcropApi.destroy();

    jcropApi = null;

        }

    }

    // @breif 이미지 업로드 함수

    function uploadImgFilePrinted() {


        // @details 업로드 파일 정보를 받아온다.

        let fileInfo = document.getElementById("uploadFile").files[0];

        let reader = new FileReader();


        reader.onload = function() {


            // @details 업로드 이미지 출력

            jQuery("#editImg").attr("src", reader.result);

            

            // @details 이미지 크기를 제목 영영과 같게 출력

            jQuery("#editImg").css("width", jQuery("h1").width());

            

            // @details 이미지 업로드 기능 제거, 추가 업로드 방지

            jQuery("#editImg").parent("a").removeAttr("onClick");

            

            // @details 편집버튼 노출

            jQuery("#editBtn").css("display", "inline");

            

            canvasDrawImage(function() {

            alert("이미지 업로드가 완료되었습니다.");

            });

        };


        if(fileInfo) {     

            // @details readAsDataURL을 통해 업로드한 파일의 URL을 읽어 들인다.

            reader.readAsDataURL(fileInfo);

        }

    }

    // @breif 캔버스 이미지 생성

    function canvasDrawImage(callback) {

        let prepImage = new Image();

        prepImage.src = jQuery("#editImg").attr("src");


        prepImage.onload = function() {


            // @details 캔버스 위에 이미지 그리기

            // jQuery("canvas") 와같은 명령은 사용할 수 없다.

            let canvas = document.querySelector("canvas");

            let canvasContext = canvas.getContext("2d");


            canvas.width = jQuery("#editImg").width();

            canvas.height = jQuery("#editImg").height();

            canvasContext.drawImage(this, 0, 0, jQuery("#editImg").width(), jQuery("#editImg").height());


            // @details 캔버스의 이미지

            let dataURI = canvas.toDataURL("image/jpeg");

            jQuery("#editImg").attr("src", dataURI);

            

            callback();

        };

    }

</script>

</head>

<body>

<input type="hidden" id="xAxis" value="0" placeholder="선택영여역의_x좌표"/>

<input type="hidden" id="yAxis" value="0" placeholder="선택영여역의_y좌표"/>

<input type="hidden" id="wLength" value="0" placeholder="선택영여역의_w넓이"/>

<input type="hidden" id="hLength" value="0" placeholder="선택영여역의_h높이"/>

<input type="file" id="uploadFile" onChange="uploadImgFilePrinted();" accept="image/*"/>

<div class="contents">

    <h1>이미지&nbsp;자르기<span>샘플</span></h1>

    <div class="imgArea">

        <a href="javascript:;" onClick="jQuery('#uploadFile').click();">

            <img id="editImg" src="./user-anonymous.png"/>

        </a>

        <br/><br/>

        <input id="editBtn" type="button" onClick="imgCropDesignate();" value="편집"/>

        <input id="cutBtn" type="button" onClick="imgCropApply();" value="자르기"/>

    </div>

    <canvas></canvas>

    <div class="copyright" style="bottom:0;">

        <p>Producer &copy; 사악미소</p>

    </div>

</div>

</body>

</html> 





# 출력결과





관련포스팅#01 : [JavaScript] 이미지 파일 썸네일 생성하기

관련포스팅#02 : [JavaScript] Canvas를 통한 이미지 회전

관련포스팅#03 : [JavaScript] Canvas로 이미지 서버에 전송하기 - Sample

관련포스팅#04 : [jQuery] JCROP을 이용한 이미지 자르기 - Sample






  1. 비밀댓글입니다
    • 2020.03.25 08:33 신고 [Edit/Del]
      디자인을 물어보시는거라면
      https://wikibook.co.kr/modern-web-design-book/
      의 예제소스의 CSS를 조금 손보아서 사용하였습니다.
      정확한 파일명은 기억이 나지 않네요

Name __

Password __

Link (Your Website)

Comment

SECRET | 비밀글로 남기기