모바일 이미지 업로드, 회전, 압축 솔루션

零下一度
풀어 주다: 2017-06-30 13:21:02
원래의
1612명이 탐색했습니다.

머리말

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

Orientation

모든 사진에 이 매개변수가 있는 것은 아니지만 휴대폰으로 촬영한 사진에는 이 매개변수가 있습니다.

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

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

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

exif.js가 Orientation을 가져옵니다:

EXIF.getData(file, function() {  var Orientation = EXIF.getTag(this, 'Orientation');});
로그인 후 복사

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

Rotation

Rotation에는 다음의rotate() 메서드를 사용해야 합니다. 캔버스.

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 < imgHeight && imgHeight > 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 type="file" id="files" ><img  src="blank.gif" id="preview" alt="모바일 이미지 업로드, 회전, 압축 솔루션" >
<script src="small-exif.js?1.1.11"></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>
로그인 후 복사

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

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿