업로드한 이미지를 미리보기하는 방법! 

참고! 

기본 이미지를 클릭하면 파일 업로드 창이 뜨도록 작업하였다. 

 

<!-- default image -->
<!-- Click on the image to open the file upload popup. -->
<label for="profile" class="form-label">
	<img src="/default.png" id="myImg">
</label>

<!-- file upload input --> 
 <input type="file" id="profile"  
 		style="display: none" 
        	accept="image/*"
		onchange="document.getElementById('myImg').src = window.URL.createObjectURL(this.files[0])" />

 

코드 설명! 

<!-- 라벨안에 이미지를 넣어 이미지를 클릭하면 파일 업로드 창이 뜨도록하였다. -->
<!-- label의 for="" 에는 file input의 id값이 들어가야한다. --> 
<label for="profile" class="form-label"> 
	<img src="/default.png" id="myImg">
</label>

<!-- 파일 업로창 --> 

 <input type="file" id="profile"  
 		style="display: none" // 파일 업로드 버튼을 숨기기 위함 
        	accept="image/*"  // 이미지만을 받기위함 
		onchange="document.getElementById('myImg').src = window.URL.createObjectURL(this.files[0])" />
        // 파일이 업로드 되는 경우 해당 파일의url을 기본이미지의 src로 변경해준다.

 

 

**** 결과 ****

 

기본이미지를 클릭하면 아래 처럼 이미지 업로드창이 뜨고 

 

업로드한 강아지 이미지가 잘 뜨는걸 볼 수 있다!

 

 

두번째 방법! 

Jquery 사용하기!  흐름은 똑같음.

$("input[type='file']").change(function(){
	$("#myImg").attr('src', URL.createObjectURL(this.files[0]));
});

 

Canvas라는 elements를 이용해 그림을 그릴 수 있는 기능을 사용할 수 있다. 

해당 캔버스엔 선, 원과 같은 그림을 그리는 기능을 사용할 수 있는데. 

Script 에서 제공하는 이벤트 기능과 합쳐 그림판을 만들 수 있는 것이다.

 

어떻게 동작하는건지 알아보자 

원리는 간단하다!

canvas위 마우스 클릭 이벤트를 감지해서 현재 마우스가 위치한 영역에 좌표를 구하고,

그 좌표에 작은 원을 그려준다. 

마우스가 이동할때 감지되는 mousemove 이벤트는 계속해서 현재 마우스의 위치를 

가져오고 그 위치에 계속해서 원을 그려주는 것이다. 

이렇게 되면 마치 우리가 연필로 그림을 그리듯한 모습을 볼수있다. 

마우스가 움직일때마다 그림을 그려주면 마우스가 움직일때마다 그림을 그리기 떄문에 

아래 코드를 보면 painting 이라는 flag를 추가했다. 

마우스가 클릭되면 이 flag를 true로 변경해 그림을 그리게 시키고.. 

마우스 클릭이 off되면 flag를 false로 변경해서 더이상 그림을 그리지 않도록 처리되는 것이다. 

 

touch 이벤트도 감지하도록 아래 코드에 적어뒀기 때문에 

아이패드, 노트북 펜슬 등으로 터치해도 기능이 잘 동작한다! 

 

아래 샘플코드를 그대로 복사하면

샘플을 확인할 수 있다~ 

 

<canvas id="canvas" ></canvas>
<script src="https://code.jquery.com/jquery-2.1.0.min.js"></script>
<script>
	
	// 캔버스 객체를 가져온다.
	var canvas = document.getElementById("canvas"),
	ctx = canvas.getContext("2d"),
	painting = false, // 그림을 그릴 상황인지 체크하는  flag
	lastX = 0, // 마지막 x 좌표 
	lastY = 0, // 마지막 y 좌표 
	lineThickness = 1; // 펜 굵기 
	
	
	// canvas 사이즈설정	
	canvas.width  = window.innerWidth;
	canvas.height = window.innerHeight;
	
	
	// 터치감지 이벤트  
	 document.body.addEventListener("touchstart", function (e) {
		if (e.target == canvas) {e.preventDefault(); }
		var touch = e.touches[0];
    	var mouseEvent = new MouseEvent("mousedown", {
			clientX: touch.clientX,
			clientY: touch.clientY
		});
		canvas.dispatchEvent(mouseEvent);
				
	}, false);
	
	
	document.body.addEventListener("touchend", function (e) {
		if (e.target == canvas) {
			e.preventDefault();
		}
		
		var touch = e.touches[0];
    	var mouseEvent = new MouseEvent("mouseup", {
			clientX: touch.clientX,
			clientY: touch.clientY
		});
		canvas.dispatchEvent(mouseEvent);
		
	}, false);
	document.body.addEventListener("touchmove", function (e) {
		if (e.target == canvas) {
			e.preventDefault();
		}
		
		var touch = e.touches[0];
		var mouseEvent = new MouseEvent("mousemove", {
			clientX: touch.clientX,
			clientY: touch.clientY
		});
		canvas.dispatchEvent(mouseEvent);
		
	}, false);
		
    
	// 마우스 이벤트 	
	canvas.onmousedown = function(e) {
	    painting = true;
	    ctx.fillStyle = "#000";
	    lastX = e.pageX - this.offsetLeft;
	    lastY = e.pageY - this.offsetTop;
	};

	canvas.onmouseup = function(e){
	    painting = false; // 마우스로 그림그리기가 끝나면 플래그를 변경해준다. 
	}

	
	// 그림을 그려주는 function
	canvas.onmousemove = function(e) {
		
	    if (painting) {
	        mouseX = e.pageX - this.offsetLeft;
	        mouseY = e.pageY - this.offsetTop;

	        // find all points between        
	        var x1 = mouseX,
	            x2 = lastX,
	            y1 = mouseY,
	            y2 = lastY;


	        var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
	        if (steep){
	            var x = x1;
	            x1 = y1;
	            y1 = x;

	            var y = y2;
	            y2 = x2;
	            x2 = y;
	        }
	        if (x1 > x2) {
	            var x = x1;
	            x1 = x2;
	            x2 = x;

	            var y = y1;
	            y1 = y2;
	            y2 = y;
	        }

	        var dx = x2 - x1,
	            dy = Math.abs(y2 - y1),
	            error = 0,
	            de = dy / dx,
	            yStep = -1,
	            y = y1;
	        
	        if (y1 < y2) {
	            yStep = 1;
	        }
	       
	        lineThickness = 3 - Math.sqrt((x2 - x1) *(x2-x1) + (y2 - y1) * (y2-y1))/10;
	        if(lineThickness < 1){
	            lineThickness = 1;   
	        }

	        for (var x = x1; x < x2; x++) {
	            if (steep) {
	                ctx.fillRect(y, x, lineThickness , lineThickness );
	            } else {
	                ctx.fillRect(x, y, lineThickness , lineThickness );
	            }
	            
	            error += de;
	            if (error >= 0.5) {
	                y += yStep;
	                error -= 1.0;
	            }
	        }

	        lastX = mouseX;
	        lastY = mouseY;

	    }
	}
    
	
	// 캔버스에 이미지를 그려준다. 
	// 나의 경우 이미지 위에 그림을 그려야해서 사용함. 
	// 생략가능 
    setBackground();
    function setBackground() {
	    var image = new Image();
	    image.onload = function() {
		    ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
	    }
	    image.src = "/resources/images/suit.png";

    }
    

</script>

 

 

결과 

 

 

* 추가적으로  Hammer.js 를 사용하면  모바일 환경에서 발생되는 더 많은 터치기능(확대, swipe, tab)을 처리할 수 있다. 

 

 

[사전환경]  * jquery 설정이 되어있을것! 

코드시작!! 

 

1. file을 받는 input과 미리보기할 이미지를 코드를 작성한다.

<input type="file" id="file" class="imgs" name="mainImg">
<img src="" />

 

2. 스크립트 작성

파일을 여러개 입력하더라도 각각 미리보기를 띄울 수 있다.

<script>
	$(function() { 
		$("input[type='file']").change(function(){
		  $(this).siblings("img").attr('src', URL.createObjectURL(this.files[0]));
	    });
	})
</script>

 

 

* 에러발생 

html 파일에서 ajax로 

통신이 이루어지는지 잘 보이기 위한 테스트 페이지를 구현하기 위해

url이 다른 서버로 요청을 보냈다. 

 

Access to XMLHttpRequest at 'file:///D:/apache/index.html' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, brave, https.

 

* 원인

같은 경로의 자원을 요청하는데 에러 메세지엔 보시다시피 origin, 즉 출처가 null 로 넘어온 script에 대한 접근이 CORS 정책에 따라 제한되었다고 나와있습니다. 

 

D:/apache/index.htm 에서 ajax로 c:/경로/js/test.js에 리소스를 요청한 건 동일 경로의 리소스를 요청한 것이 아니고
D:/apache/index.htm 에서 null/js/test.js로 리소스를 요청한 것이 되어 CORS에러가 발생한 것입니다.

 

 

 

웹 서버에 올려 프로토콜 호스트 포트를 같게 만들면 CORS 에러가 해결되는데,

 

같게 할 수 없는 상황에선 특정 플러그인을 사용하거나 jsonp 방식을 사용한다. 

 

+ Recent posts