이 역시 티몬 구매후기에서 이미지 업로드와 관련된 기능을 적용하면서 나온 내용을 정리 차원에서 적어 둡니다.

 

구매후기 작성 시 이미지를 선택해서 업로드를 하게 되는데, 기존에는 이미지의 사이즈를 제한하는 기능이 있었고 이로 인해 이미지 제한에 걸려 이미지를 업로드 하지 못하거나, 업로드 된 원본 이미지도 용량이 너무 큰 문제가 있었습니다. (장당 3MB)

 

아무런 제약 없이 이용자는 이미지를 마음껏 올릴 수 있으려면 이미지 리사이즈가 필요한데, 서버단에서 용량 리사이징을 하게 되면 아까운 네트웍 비용이 들어가게 되므로 클라이언트 단에서 용량을 줄일 필요가 있었습니다.

그래서 사용하게 된 것이 HTML5의 Canvas 기능이죠.

물론 이전에 HTML5를 제대로 사용해 본 적이 없어서...

모든 기능은 최고의 방법이 구글링을 통해 적용했습니다.

그리고 HTML5의 Canvas가 적용되지 않는 브라우저를 위해서라도 (망할 IE -.-;;) 기존 소스 코드는 남겨두고 분기 처리를 해야 했습니다.

 

기본적으로 jQuery를 사용 했습니다.

아... 그리고 기본적으로 저는 자바스크립트를 잘 못하는 개발자이므로 발코딩이 나와도 이해해 주세요 ^^

간단한 설명은 주석으로 달았습니다.

// html5의 Canvas를 사용해서 이미지 리사이징이 가능한지 판별하는 메소드
function isImageResizable() {
	var isCanvasUsable = !!document.createElement('canvas').getContext;
	var isLowerIE = false;

	if($.browser.msie) {
		if($.browser.version < 10) {	// IE9은 Canvas는 쓸 수 있지만 file input에서 file Object를 가져오지 못해 제외
			isLowerIE = true;
		}
	}

	return isCanvasUsable && !isLowerIE;
}

<html5의 Canvas를 사용해서 이미지 리사이징이 가능한지 판별하는 메소드>

 

<!-- file input을 form 밖에 두는 이유는 리사이징 한 내용을 동적으로 form 안에 넣어 submit 하기 위함 -->
<a href="#">사진등록<input type="file" name="Filedata" title="사진등록" id="_inputFile"></a>
<form id="_imageUploadForm" method="post" action="Action Url 입력" enctype="multipart/form-data">
<input type="hidden" id="file_name" name="file_name" value="" />
</form>

<html form>

 

// fileInput Object에 값이 변경될 때
welInputUpload.change(function(){
	// 이미지 리사이즈 가능한 브라우져가 아니라면 일반적인 업로드로...
	if(isImageResizable() == false) {
		$("#fileSelector").appendTo("#_imageUploadForm");
		welUploadForm.submit();
	} else {	// 이미지 리사이즈가 브라우저단에서 가능하다면 html5 사용...
		var file = welInputUpload.prop('files')[0];	// file Object get... 
		if(file.type.match(/image.*/)) {
			// Load the image
			var reader = new FileReader();
			reader.onload = function (readerEvent) {
				var image = new Image();
				image.onload = function (imageEvent) {

					// Resize the image
					var canvas = document.createElement('canvas'),
					max_size = 1280,
					width = image.width,
					height = image.height;

					if (width > height) {
						if (width > max_size) {
							height *= max_size / width;
							width = max_size;
						}
					} else {
						if (height > max_size) {
							width *= max_size / height;
							height = max_size;
						}
					}
					canvas.width = width;
					canvas.height = height;
					canvas.getContext('2d').drawImage(image, 0, 0, width, height);
					var dataUrl = canvas.toDataURL('image/jpeg');
					//var dataUrl = canvas.toDataURL('image/jpeg', 0.90);	// 이미지 퀄리티 조절도 가능...
					var resizedImage = dataURLToBlob(dataUrl);	// 이미지를 바이너리 형태로 변환?
					
					// 이미지가 리사이즈 되었으면 파일 업로드하는 메소드 호출
					$.event.trigger({
						type: "imageResized",
						blob: resizedImage,
						url: dataUrl
					});
					return false;
				}
				image.src = readerEvent.target.result;
			}
			reader.readAsDataURL(file);
		}
	}
	return false;
});

<file input을 통해 file을 선택했을 경우 동작하는 메소드>

 

// String to Binary 메소드 같은데 구글링으로 얻어온 것이라 자세한 내용은 모름 ㅎㅎ
var dataURLToBlob = function(dataURL) {
	var BASE64_MARKER = ';base64,';
	if (dataURL.indexOf(BASE64_MARKER) == -1) {
		var parts = dataURL.split(',');
		var contentType = parts[0].split(':')[1];
		var raw = parts[1];

		return new Blob([raw], {type: contentType});
	}

	var parts = dataURL.split(BASE64_MARKER);
	var contentType = parts[0].split(':')[1];
	var raw = window.atob(parts[1]);
	var rawLength = raw.length;

	var uInt8Array = new Uint8Array(rawLength);

	for (var i = 0; i < rawLength; ++i) {
		uInt8Array[i] = raw.charCodeAt(i);
	}

	return new Blob([uInt8Array], {type: contentType});
}

<String을 Binary로 변환해 주는 메소드. 구글링 결과물로 정확한 내용은 검토해 보지 못함>

 

 

$(document).on("imageResized", function (event) {
	var data = new FormData($("form[id*='_imageUploadForm']")[0]);
	if (event.blob && event.url) {
		// 리사이즈 된 이미지 첨부, 파일명은 실제 선택한 파일명을 넘겨 서버단에서 처리하도록...
		data.append('Filedata', event.blob);
		data.append('file_name', $("#_inputFile").prop('files')[0].name);

		$.ajax({
			url: "Action Url 입력",
			data: data,
			cache: false,
			contentType: false,
			processData: false,
			type: 'POST',
			success: cbUpload,
			error : function(err){
				alert("파일 업로드를 할 수 없습니다. 잠시 후 다시 시도해 주세요.");
			}
		});
	}
});

<리사이징 된 파일을 업로드 하는 메소드>

 

 




WRITTEN BY
체리필터
프로그램 그리고 인생...

트랙백  0 , 댓글  4개가 달렸습니다.
  1. 안녕하세요.
    서버로 전송해서 서버에서 파일 저장 처리하는 부분은 어떻게 구현하셨는지 알려 주실 수 있을까요? ^^
    지금 jsp 환경에서 하고 있습니다.
    • 서버 저장은 노멀한 내용이라서 그냥 구글링 하면 나오는 거랑 다를 거 없을 것 같습니다.
      파일 객체이니 파일 객체 받아서 저장하는 일반적인 소스 검색해 보시면 좋을 것 같습니다.
  2. 후기 업로드 이미지 작업 중이었는데, 도움이 많이 되었습니다.
    완전 감사합니다!
secret


구매후기 이미지 업로드에서 오류가 나고 있어서 해당 내용을 검토 중에 알게 된 내용을 정리합니다.

기본적으로 아래와 같은 방식으로 업로드가 되고 있습니다.

 

브라우저 -> php -> Java

 

그런데 문제는 어느 한쪽의 문제가 아니라 php, Java 둘다 문제가 발생...

그리고 문제의 원인은 둘다 Version Up이였습니다.

 

1. 먼저 Java

Error Message가 "Required MultipartFile parameter 'file' is not present" 라고 발생.

구글링 하니 http://stackoverflow.com/questions/25830503/spring-mvc-http-status-400-required-multipartfile-parameter-file-is-not-pre 가 검색 됨.

 

아래와 같은 방식으로 수정

 

AS-IS

<bean id="multipartResolver" class="**org.springframework.web.multipart.commons.CommonsMultipartResolver**" />

TO-BE

<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver" />

 

2. 다음으로 PHP

 

PHP에서 Java 쪽으로 파일을 올릴 때는 CURL을 사용했는데 기존에 /tmp에 올라온 임시 파일을 읽어 들일 때는 @를 사용해서 리소스를 읽어 들였음.

php 5.5.0 기준 Deprecated 된 기능이라서 다른 방법으로 수정

if (!function_exists('curl_file_create')) {
	$data = array(
		'Filedata' => '@'.$file['tmp_name'].';filename='.$file['name'].';type='.$file['type']
	);
	$ch = curl_init();
} else {
	$ch = curl_init($api_url.$uri);
	$cfile = curl_file_create($file['tmp_name'], $file['type'], $file['name']);

	$data = array(
		'Filedata' => $cfile
	);
}

 

 




WRITTEN BY
체리필터
프로그램 그리고 인생...

트랙백  0 , 댓글  0개가 달렸습니다.
secret


집에 컴퓨터를 새로 사가지고 윈도우와 각종 프로그램을 설치했는데...
이상하게 특정 이미지만 안보이는 현상이 발생하네요.
플래시도 특정 플래시만 안보이고...
iframe의 경우에도 특정 iframe은 안보입니다.
현상은 아래에 이미지 캡쳐로 해 놨습니다.

또한 로그인이 잘 안되는 경우도 있네요 -.-;;
쿠키가 적용 되는 것 같은데... 어떤 페이지는 쿠키를 인식하고 어떤 페이지는 인식하지 못하고... -.-;;

인터넷에 있는 여러가지 질문 답변을 찾아서 해 봐도 안되고..
IE가 문제인 듯 해서 IE7으로 업그레이드를 해 봐도 그렇네요.
FF도 역시 문제입니다.
흐... 도대체 뭐가 문제인지 모르겠네요.
IE의 옵션의 도구에 봐도 딱히 문제 될 만한게 안보이고... -.-;;

윈도우를 다시 깔아야 할려나요?

01234




WRITTEN BY
체리필터
프로그램 그리고 인생...

트랙백  0 , 댓글  3개가 달렸습니다.
  1. 비밀댓글입니다
  2. 브카입니다.
    제가 볼땐....
    그리스 몽키나 IEOY 같은 블라우저 프로그램에서 광고 차단을 설정 하신듯 합니다.
    FF까지 그렇다는 것은 아무래도 그리스몽키가 적용된 광고 차단이나 광고 차단 Plug-in을 설치 하신듯.....
    ^^;
    요즘 툴바에서도 광고 차단이 제공되는 지는 모르겠지만, 올리신 이미지에서 보면 주로 광고만 안뜨는 것 같은데요..
    도움이 되셨으면 하네요~~
    • 방화벽으로 존 알람을 깔았었는데..
      이게 banner 관련해서 high로 설정 되어 있더군요 ^^
      그래서 img src로 되지 않고 다른 방법으로 이미지를 뿌려주는 경우에 이미지를 차단했던 것 같습니다. ^^

      감사합니다. ^^
secret


http://imageparody.com/

http://imageparody.com/


참고 - http://imageparody.com/

흠... 이거 괜찮네 ㅎㅎ
gd 이용해서 만들었나 보네 ㅎ



WRITTEN BY
체리필터
프로그램 그리고 인생...

트랙백  0 , 댓글  2개가 달렸습니다.
  1. ㅋㅋ..언제 소주사업에까지 진출하셨나요?
secret


처음으로 팁텍을 올리는 군요... ^^;;
이미지 파일일 경우... 파일을 업로드 하기 전에 미리 크기를 체크하는 스크립트입니다.
다른 파일일 경우에는 안 해 봤는데... 아마도 안될꺼 같구요...^^;;
이미지 파일은 잘 되는 거 같습니다.^^;;

다음은 소스입니다...

***************************************************************************

<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> New Document </title>
<meta name="Generator" content="EditPlus">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<script language='javascript'>
function fileSize() {
   alert(document.aaa.pre.fileSize);
}

function dreamkos_imgview()
{
   img_pre = 'pre';
   if(event.srcElement.value.match(/(.jpg|.jpeg|.gif|.png)/)) {
       document.images[img_pre].src = event.srcElement.value;
       document.images[img_pre].style.display = '';
    }
   else {
       document.images[img_pre].style.display = 'none';
   }
}
</ script>


<table bordercolordark="#ffffff" bordercolorlight="#bccad5" bgcolor="#e4e9de" border="1" cellpadding="1" cellspacing="0">

<form name="aaa">
<tbody><tr>
<td><font color="green">♤</font> 이미지를 선택하십시요. <font color="green">♤</font></td>
</tr>
<tr>
<td><input name="dreamkos_file" size="32" onchange="dreamkos_imgview()" type="file"></td>
</tr>
<tr>
<td><img id="pre" style="display: none;" border="0"></td>
</tr>

<a href="javascript:fileSize();">aaa</a>

</tbody>

</form></table>



WRITTEN BY
체리필터
프로그램 그리고 인생...

트랙백  0 , 댓글  0개가 달렸습니다.
secret