>웹 프론트엔드 >JS 튜토리얼 >모바일 이미지 업로드 회전 및 압축 문제 해결

모바일 이미지 업로드 회전 및 압축 문제 해결

青灯夜游
青灯夜游앞으로
2018-10-15 17:20:042163검색

이 글에서는 모바일 기기에 업로드된 이미지를 회전하고 압축할 때 발생하는 문제에 대한 해결책을 제시합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.

머리말

휴대폰에서 웹페이지의 입력태그를 통해 사진을 촬영하고 업로드할 경우, 아이폰 및 개별 삼성모바일을 포함한 일부 휴대폰에서는 사진이 90도 회전되는 문제가 발생할 수 있습니다. 전화기. 이 문제는 휴대폰을 세로로 촬영할 때만 발생하며, 가로로 촬영한 사진은 정상적으로 표시됩니다. 따라서 휴대폰의 카메라 각도를 조정하여 사진을 회전시키면 이 문제를 해결할 수 있습니다.

Orientation

이 매개변수는 모든 사진에서 사용할 수 없지만 휴대폰으로 촬영한 사진에는 이 매개변수가 있습니다.

회전 각도 매개변수 값
1
90° 시계 방향 6
90° 시계 반대 방향 8
180° 3

매개변수가 1이면 디스플레이가 정상이고, 이러한 가로 샷에서는 디스플레이가 정상입니다. 즉, Orientation = 1인 휴대폰에서는 세로 샷 매개변수가 6입니다.

Orientation 매개변수를 얻으려면 EXIF.js 라이브러리를 통해 조작할 수 있습니다. EXIF.js는 기능이 많고 크기가 크므로 압축하지 않은 상태에서는 30k로 모바일 페이지 로딩에 큰 영향을 미칩니다. 그리고 Orientation 정보만 가져오면 되므로 EXIF.js 라이브러리에서 일부 코드를 삭제하고 코드를 몇 KB로 줄였습니다.

exif.js가 오리엔테이션을 가져옵니다:

EXIF.getData(file, function() {  
    var Orientation = EXIF.getTag(this, 'Orientation');
});

file은 입력 파일 형식으로 업로드된 파일입니다. 업로드된 파일은 fileReader.readAsDataURL(file)을 통해 미리 볼 수 있습니다. 이에 대해 확실하지 않은 경우 다음을 확인할 수 있습니다. HTML5 고급 시리즈: 파일 업로드 및 다운로드

Rotation

회전에는 캔버스 회전이 필요합니다. ( ) 방법.

ctx.rotate(angle);

rotate 메소드의 매개변수는 회전 호입니다. 각도는 라디안으로 변환되어야 합니다. 도 * Math.PI / 180

회전의 중심점은 기본적으로 캔버스의 시작점, 즉 (0, 0)에 있습니다. 회전의 원리는 다음과 같습니다.

모바일 이미지 업로드 회전 및 압축 문제 해결
회로도를 회전

한 후 (0, 0) 지점에서 drawImage()를 수행하면 그려진 위치는 왼쪽 그림에서 90도 회전한 후의 위치가 되며 보이는 영역은 아닙니다. 회전 후 좌표축도 회전하여 가시 영역에 표시하려면 이때 y축의 반대 방향으로 (0, 0) 지점을 이동해야 합니다. (0, -y )입니다.

마찬가지로 -90도 회전한 후의 시작점은 (-x, 0)이고, 180도 회전한 후의 시작점은 (-x, -y)입니다.

압축

휴대폰으로 찍은 사진은 용량이 너무 크고, base64로 인코딩한 사진은 원본 사진보다 크기가 커지므로 업로드 시 압축이 꼭 필요합니다. 오늘날의 휴대폰은 매우 높은 픽셀을 가지고 있으며, 촬영된 사진의 너비와 높이는 수천 픽셀에 달하므로 캔버스를 사용하여 사진을 렌더링하는 것은 상대적으로 느립니다.

그래서 첫 번째 단계는 업로드된 사진의 너비와 높이를 제한하고 너비나 높이가 특정 범위를 초과하는지 확인한 다음 너비와 높이를 동일하게 압축하는 것입니다.

var ratio = width / height;if(imgWidth > imgHeight && imgWidth > xx){
    imgWidth = xx;
    imgHeight = Math.ceil(xx / ratio);
}else if(imgWidth  yy){
    imgWidth = Math.ceil(yy * ratio);
    imgHeight = yy;
}

두 번째 단계는 canvas.toDataURL() 메서드를 통해 사진 품질을 압축하는 것입니다.

canvas.toDataURL("image/jpeg", 1);

toDataURL() 메서드는 이미지 표시가 포함된 데이터 URI를 반환합니다. 두 개의 매개변수를 사용하세요. 첫 번째 매개변수는 이미지 형식이고 기본값은 image/png입니다. 두 번째 매개변수는 압축 품질입니다. 지정된 이미지 형식이 image/jpeg 또는 image/webp인 경우 이미지 품질을 0에서 1까지 선택할 수 있습니다.

Summary

위 내용을 바탕으로 예시 코드에는 간소화된 EXIF.js 라이브러리 주소가 포함되어 있습니다: file-demo

주요 핵심 코드는 다음과 같습니다.

<input><img  alt="모바일 이미지 업로드 회전 및 압축 문제 해결" >
<script></script>
<script>
    var ipt = document.getElementById(&#39;files&#39;),
    img = document.getElementById(&#39;preview&#39;),
    Orientation = null;
    ipt.onchange = function () {    
        var file = ipt.files[0],
    reader = new FileReader(),
    image = new Image();    
    if(file){
        EXIF.getData(file, function() {  
            Orientation = EXIF.getTag(this, &#39;Orientation&#39;);
        });
        reader.onload = function (ev) {
            image.src = ev.target.result;
            image.onload = function () {     
                var imgWidth = this.width,
                imgHeight = this.height;                // 控制上传图片的宽高 
                if(imgWidth > imgHeight && imgWidth > 750){
                    imgWidth = 750;
                    imgHeight = Math.ceil(750 * this.height / this.width);
                }else if(imgWidth < imgHeight && imgHeight > 1334){
                    imgWidth = Math.ceil(1334 * this.width / this.height);
                    imgHeight = 1334;
                }                
                var canvas = document.createElement("canvas"),
                ctx = canvas.getContext(&#39;2d&#39;);
                canvas.width = imgWidth;
                canvas.height = imgHeight; 
                if(Orientation && Orientation != 1){
                    switch(Orientation){                        
                    case 6: // 旋转90度
                        canvas.width = imgHeight;    
                        canvas.height = imgWidth;    
                        ctx.rotate(Math.PI / 2);                            
                        // (0,-imgHeight) 从모바일 이미지 업로드 회전 및 압축 문제 해결那里获得的起始点
                        ctx.drawImage(this, 0, -imgHeight, imgWidth, imgHeight); 
                        break;                        
                     case 3: // 旋转180度
                        ctx.rotate(Math.PI);    
                        ctx.drawImage(this, -imgWidth, -imgHeight, imgWidth, imgHeight); 
                        break;                        
                     case 8: // 旋转-90度
                        canvas.width = imgHeight;
                        canvas.height = imgWidth; 
                        ctx.rotate(3 * Math.PI / 2);
                        ctx.drawImage(this, -imgWidth, 0, imgWidth, imgHeight);
                        break;
                    }
                }else{
                    ctx.drawImage(this, 0, 0, imgWidth, imgHeight);
                }
                img.src = canvas.toDataURL("image/jpeg", 0.8);
            }
        }
        reader.readAsDataURL(file);
    }
}</script>

요약: 위 내용은 전체 내용입니다. 이 글이 모든 분들의 공부에 도움이 되었으면 좋겠습니다. 더 많은 관련 튜토리얼을 보려면 JavaScript 비디오 튜토리얼, jQuery 비디오 튜토리얼, bootstrap 튜토리얼을 방문하세요!

위 내용은 모바일 이미지 업로드 회전 및 압축 문제 해결의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제