ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [이미지] 모바일에서 사진 찍어 이미지 등록 시 회전 막기
    JAVA/이미지 2019. 11. 11. 19:56
    반응형

    이번 포스팅에서는 모바일에서 input[type=file]을 사용하여 서버로 이미지 등록 시 회전되는걸 막으려고 한다.

    필자는 실제로 회사 프로젝트 때 활용하여 사용하였다. 

    스마트폰 기종에 따라 사진을 찍으면 이미지가 자동으로 회전되서 업로드가 된다.

    먼저 본질적으로 막는 방법은 없는 것 같다.

    그래서 이미지를 등록 시 자바스크립트 플러그인을 통하여 orientation 값에 따라 서버에서 강제로 이미지를 회전 시켜 저장하려한다.

     

     

    먼저 자바스크립트를 통하여 orientation 값을 구하려고 한다.

    플러그인을 다운받자.

    load_image.zip
    0.13MB

    플러그인을 사용하여 html 코드로 테스트 해보려고 한다.

    데스크탑에서 테스트하면 orientation 값이 항상 1일 것이다.

    모바일에서 테스트 하려면 

    1. 닷홈 무료 호스팅

    2. 서버에 jsp 배포

    편한걸로 하자.

    <!DOCTYPE html>
    <html lang="ko">
    
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
        <script src="js/load_image/load-image.js"></script>
        <script src="js/load_image/load-image-scale.js"></script>
        <script src="js/load_image/load-image-meta.js"></script>
        <script src="js/load_image/load-image-fetch.js"></script>
        <script src="js/load_image/load-image-orientation.js"></script>
        <script src="js/load_image/load-image-exif.js"></script>
        <script src="js/load_image/load-image-exif-map.js"></script>
        <script src="js/load_image/load-image-iptc.js"></script>
        <script src="js/load_image/load-image-iptc-map.js"></script>
        <script src="js/load_image/vendor/jquery.Jcrop.js"></script>
    </head>
    
    <body>
        <input type="file" id="img">
        <script>
            $('#img').on('change', dropChangeHandler);
    
            function dropChangeHandler(e) {
                e.preventDefault()
                e = e.originalEvent
    
                var files = e.target.files;
                var filesArr = Array.prototype.slice.call(files);
    
                filesArr.forEach(function(f, index) {
                    fileName = $("#img").val();
                    fileName = fileName.slice(fileName.indexOf(".") + 1).toLowerCase();
    
                    if (fileName != "jpg" && fileName != "png" && fileName != "gif" && fileName != "bmp" && fileName != "apng" && fileName != "avif" && fileName != "bpg" && fileName != "dds" && fileName != "dng" && fileName != "exr" && fileName != "jpeg" && fileName != "heif" && fileName != "psd" && fileName != "raw" && fileName != "rgbe" && fileName != "tiff" && fileName != "webp") {
                        alert('이미지 파일만 업로드 가능합니다.');
                        $("#img").val("");
                        return;
                    }
    
                    var reader = new FileReader();
                    reader.onload = function(e) {
                        var file = f;
                        var options = {
                            maxWidth: 500,
                            canvas: true,
                            pixelRatio: window.devicePixelRatio,
                            downsamplingRatio: 0.5,
                            orientation: true
                        }
                        if (!file) {
                            return
                        }
    
                        displayImage(file, options)
    
                    }
                    reader.readAsDataURL(f);
    
                });
            }
    
            function displayImage(file, options) {
                currentFile = file
                if (!loadImage(file, updateResults, options)) {
                    result.children().replaceWith()
                }
            }
    
            function updateResults(img, data) {
                var fileName = currentFile.name
                var href = img.src
                var dataURLStart
                var content
                if (!(img.src || img instanceof HTMLCanvasElement)) {
    
                } else {
    
                    displayMetaData(data);
                }
            }
    
            function displayMetaData(data) {
    
                if (!data) return
                var exif = data.exif
                var iptc = data.iptc
    
                if (exif) {
                    if (exif.get('Orientation') == null) {
                        orientation = 1;
                    } else {
                        orientation = exif.get('Orientation');
                    }
                } else {
                    orientation = 1;
                }
    
                alert(orientation);
    
            }
    
        </script>
    </body>
    
    </html>
    

     

     

     

    서버로 이미지를 업로드 할 때 orientation 값도 같이 업로드 하자.

    이미지 회전 하는 소스만 적었다.

    일단 먼저 서버에 업로드한 이미지를 저장한다.

    자바스크립트 플러그인을 이용해서 추출한 orientation 값에 따라 회전 값을 적었다.

     

    [1, 2] = 정상적인 이미지

    [3, 4] = 180도 회전된 이미지

    [5, 6] = 270도 회전된 이미지

    [7, 8] = 90도 회전된 이미지

     

    그러므로 아래처럼 회전 시켜야한다.

    [1, 2] = 아무 처리 필요없음

    [3, 4] = 180도 회전 시킴

    [5, 6] = 90도 회전 시킴

    [7, 8] = 270도 회전 시킴

     

    자바 Graphics2D을 이용하여 rotate를 시키고 이미지를 저장하면 정삭적인 이미지가 저장이 될 것이다.

    switch (orientation) {
    case 1:
    	orientation = 0;
    	break;
        
    case 2:
    	orientation = 0;
    	break;	
        
    case 3:
    	orientation = 2;
    	break;
           
    case 4:
    	orientation = 2;
    	break;
    
    case 5:
    	orientation = 1;
    	break;
    
    case 6:
    	orientation = 1;
    	break;
    
    case 7:
    	orientation = 3;
    	break;
    
    case 8:
    	orientation = 3;
    	break;
    
    }
    		
    if(orientation != 0) {
    	BufferedImage oldImage = ImageIO.read(new FileInputStream(saveFilePath + newInfImgFileName));
    	BufferedImage newImage1 = new BufferedImage(oldImage.getHeight(),oldImage.getWidth(), oldImage.getType());
    	Graphics2D graphics = (Graphics2D) newImage1.getGraphics();
    	graphics.rotate(Math.toRadians(90 * orientation), newImage1.getWidth() / 2, newImage1.getHeight() / 2);
    	graphics.translate((newImage1.getWidth() - oldImage.getWidth()) / 2, (newImage1.getHeight() - oldImage.getHeight()) / 2);
    	graphics.drawImage(oldImage, 0, 0, oldImage.getWidth(), oldImage.getHeight(), null);
    	ImageIO.write(newImage1, ext, new FileOutputStream(saveFilePath + newInfImgFileName));
    }
    반응형
Designed by Tistory.