TIP게시판

제목 모바일 환경에서의 이미지 업로드
글쓴이 도라에몽 작성시각 2022/12/28 20:20:08
댓글 : 2 추천 : 0 스크랩 : 0 조회수 : 5483   RSS

회사 앱(하이브리드) 특성상 모바일 상에서 카메라로 찍어서 이미지를 자주 올리도록 되어있습니다. 

이미지를 올릴때 용량이 크면 중간에 새로고친다던지..

앱이 죽은줄 알고 앱을 닫는다던지.. 등등의 액션으로 인해서 

파일이 안올라온다거나.. 이탈하는 회원이 생깁니다. 

그래서 고민하다가 좋은 참고자료를 찾았습니다. 

원본은 https://stackoverflow.com/questions/23945494/use-html5-to-resize-an-image-before-upload 여기에서 확인

 

<input name="imagefile[]" type="file" id="takePictureField" accept="image/*" onchange="uploadPhotos('test/html5prc');" />
<form id="uploadImageForm" method="post" enctype="multipart/form-data" action="/test/html5prc">
       <input type="text" id="name" value="text-field" />
       <input type="hidden" name="upfile_blob" id="upfile_blob" value="" />
       <input type="submit" name="submit" id="uploadImageForm_btn" value="업로드"/>
 </form>

input=file 필드를 form 밖에 둔 이유는 해당 첨부파일이 업로드되지 않도록 하기 위함.

 

window.uploadPhotos = function(url){
    // Read in file
    var file = event.target.files[0];

    // Ensure it's an image
    if(file.type.match(/image.*/)) {
        var reader = new FileReader();
        reader.onload = function (readerEvent) {
            var image = new Image();
            image.onload = function (imageEvent) {
                var canvas = document.createElement('canvas'),
                    max_size = 1024,  /* 리사이즈될 이미지의 크기 지정 */
                    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 resizedImage = dataURLToBlob(dataUrl);
                $("#upfile_blob").val(dataUrl);
                $.event.trigger({type: "imageResized",blob: resizedImage,url: dataUrl});
            }
            image.src = readerEvent.target.result;
        }
        reader.readAsDataURL(file);
    }
};

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});
}

$(document).on("imageResized", function (event) {
    if (event.blob && event.url) {
        $("#uploadImageForm_btn").click();
    }
});

업로드가 파일이 아니고 text필드의 값으로 넘어왔으므로 

DB에 blog 필드에 저장해도 되고 폴더에 저장해도 됩니다. 

폴더에 저장하시려면 아래와 같이 변환해서 저장하면 됩니다. 

$blob = $_POST["upfile_blob"];
$arr = explode(",", $blob);
unset($arr[0]);
$blob = base64_decode(implode("",$arr));
$filename = time() . ".jpeg";
   
file_put_contents('./img/event_temp/'.$filename, $blob);

 

max_width를 1024 정도로 했을때 5~6매가 씩이나 되는 이미지도 200kbyte 정도 이하로 리사이즈 되어 업로드 됩니다. 

모바일 환경에서 파일 업로드 고민 하시는 분들에게는 좋은 팁이 될듯 합니다. 

 

참고한 URL 

 다음글 captcha font size 폰트 사이즈가 바뀌지 ...
 이전글 자바스크립트 이미지 에디터

댓글

변종원(웅파) / 2022/12/29 12:14:54 / 추천 0

특정 상황을 우회하려고 한 방식이나 db 측면에서는 좋지 않은 방식입니다.

blob 데이터가 많아질 경우 속도문제도 있고, 일반적인 디스크저장보다 db용량이 비용이 더 비쌉니다. 이런 점을 감안해서 blob으로 파일저장하셔야 합니다. ^^

한대승(불의회상) / 2022/12/29 14:35:32 / 추천 0

JS를 통하여 이미지 리사이즈를 진행하는군요.

APP 연동 안하는 경우 유용하게 잘 쓸수 있을것 같습니다.

공유 감사합니다.