>  기사  >  웹 프론트엔드  >  exfe.js와 canvas를 사용하여 모바일 IOS에서 사진 촬영 및 업로드 시 사진이 뒤집히는 문제 해결(코드 포함)

exfe.js와 canvas를 사용하여 모바일 IOS에서 사진 촬영 및 업로드 시 사진이 뒤집히는 문제 해결(코드 포함)

不言
不言앞으로
2018-11-16 17:26:174796검색

이 글의 내용은 모바일 IOS에서 사진을 찍을 때 사진이 뒤집히는 문제를 해결하기 위해 exfe.js와 캔버스를 사용한 내용입니다. 필요한 친구들이 참고할 수 있으면 좋겠습니다. 당신에게 도움이 됩니다.

처음 프론트엔드 작업을 시작한 지 약 1년쯤 되었을 때 회사에서 아바타 업로드 기능이 있는 웹앱을 만들었던 것으로 기억합니다. Apple 사용자가 사진을 찍고 아바타를 업로드하면 뒤집힐 것이라고 당시 몇몇 프런트 엔드 동급생이 나에게 경고했지만 오후 내내 문제가 해결되지 않았고 문제가 나에게 전달되었으며 30분의 시간이 있었습니다. 퇴근하세요. 당시 저는 혼란스러웠고, 가장 먼저 든 생각은 '이게 뒤집혔는지 어떻게 알 수 있지?'였습니다. 안드로이드에는 문제가 없고, 애플 휴대폰의 앨범에 있는 일부 사진에는 문제가 없습니다. js에 이 기능이 있다고 판단할 수 있나요? 온라인으로 정보를 확인했는데, 확실히 있었습니다! 그게 exfe.js 인데, 이때 팀장 언니가 이미 저녁을 사왔고, 사장님도 조의를 표하러 오셨는데, 드디어 저녁 9시가 되었네요. 해결되었습니다.

2년이 지나서 어제 또 이런 문제가 생겼습니다. 이전 회사를 떠난 지 1년 반이 되었습니다. 현재 회사에서는 할로윈 이벤트를 진행 중이며, 사진 업로드와 유령 얼굴 합성도 포함됩니다. 며칠 전 관리자(우리는 개발자 몇 명과 함께 멀리 떨어져 있습니다)가 저녁에 퇴근하려고 할 때 프로젝트 관리자가 "iOS 사진 뒤집기, 해결하세요. 오늘 밤 온라인에 접속해야 합니다. 야근", 만 말이 내 마음을 질주하고 있다는 것, 1은 iOS에 이런 문제가 있다는 것을 잊었다는 것, 2는 2일 동안 당신에게 보내졌다는 것, 그리고 당신이 퇴근하려고 할 때 당신이 나에게 말했다는 것입니다 문제가 있어서 초과근무를 해야 했어요! 저녁 약속을 취소해야 해요! 아직 무료입니다! 위로 식사도 없었고, 사과도 없었습니다. 나는 그래도 야근을 할 의향이 있었고, 쓴웃음을 지으며 "알겠습니다. 다음에 미리 테스트해 보겠습니다."라고 대답했습니다. , 그리고 처리가 더 빠르게 이루어졌고, 7시 이후에 완료되었습니다. 이후 배포 문제가 발생하면 더 이상 내 문제가 아닙니다. 다시 거의 9시가 됩니다.

그저 한숨만 나오는 거의 비슷한 장면이에요.

코드를 업로드

html 부분

<input type="file" accept="image/*" id="uploadImage" capture="camera" onchange="selectFileImage(this);" />
<img alt="preview" src="" id="myImage"/>

exfe.js하여 이미지 정보를 읽어보세요. 저희가 업로드한 이미지에는 많은 정보가 있습니다

//获取照片方向角属性,用户旋转控制
EXIF.getData(file, function() {
    EXIF.getAllTags(this);
    Orientation = EXIF.getTag(this, 'Orientation');
    console.log(Orientation);
});

Orientation의 값은 1, 3, 6, 8, etc.는 각각 시계 방향 0°, 180°, 90°, 시계 반대 방향 90°를 나타냅니다.

이미지의 회전 각도를 알면 캔버스를 사용하여 이를 처리하고 최종적으로 원하는 결과를 얻을 수 있습니다. 는 인터넷에서 발췌한 코드입니다. 특별한 기능이 있는 경우 로직을 직접 작성해야 합니다. 즉, 각도 판단, 운영체제 판단, 캔버스로 다시 그리기, base64 생성, 마지막으로 연산을 수행해야 합니다. 그림을 표시하는 돔입니다.

업코드

function selectFileImage(fileObj) {
        var file = fileObj.files['0'];
        //图片方向角 
        var Orientation = null;
        if (file) {
            //获取照片方向角属性,用户旋转控制
            EXIF.getData(file, function() {
                EXIF.getAllTags(this);
                Orientation = EXIF.getTag(this, 'Orientation');
                console.log(Orientation)
            });
            var oReader = new FileReader();
            oReader.onload = function(e) {
                var image = new Image();
                image.src = e.target.result;
                image.onload = function() {
                    var expectWidth = this.naturalWidth;
                    var expectHeight = this.naturalHeight;

                    if (this.naturalWidth > this.naturalHeight && this.naturalWidth > 800) {
                        expectWidth = 800;
                        expectHeight = expectWidth * this.naturalHeight / this.naturalWidth;
                    } else if (this.naturalHeight > this.naturalWidth && this.naturalHeight > 1200) {
                        expectHeight = 1200;
                        expectWidth = expectHeight * this.naturalWidth / this.naturalHeight;
                    }
                    var canvas = document.createElement("canvas");
                    var ctx = canvas.getContext("2d");
                    canvas.width = expectWidth;
                    canvas.height = expectHeight;
                    ctx.drawImage(this, 0, 0, expectWidth, expectHeight);
                    var base64 = null;
                    //修复ios
                    if (navigator.userAgent.match(/iphone/i)) {
                        console.log('iphone');
                        //如果方向角不为1,都需要进行旋转 
                        if(Orientation != "" && Orientation != 1){
                            alert('旋转处理');
                            switch(Orientation){
                                case 6://需要顺时针(向左)90度旋转
                                    rotateImg(this,'left',canvas);
                                    break;
                                case 8://需要逆时针(向右)90度旋转
                                    rotateImg(this,'right',canvas);
                                    break;
                                case 3://需要180度旋转
                                    rotateImg(this,'right',canvas);//转两次
                                    rotateImg(this,'right',canvas);
                                    break;
                            }
                        }
                        base64 = canvas.toDataURL("image/jpeg", 1);
                    }else if (navigator.userAgent.match(/Android/i)) {// 修复android
                        var encoder = new JPEGEncoder();
                        base64 = encoder.encode(ctx.getImageData(0, 0, expectWidth, expectHeight), 80);
                    }else{
                        if(Orientation != "" && Orientation != 1){
                            switch(Orientation){
                                case 6://需要顺时针(向左)90度旋转
                                    rotateImg(this,'left',canvas);
                                    break;
                                case 8://需要逆时针(向右)90度旋转
                                    rotateImg(this,'right',canvas);
                                    break;
                                case 3://需要180度旋转
                                    rotateImg(this,'right',canvas);//转两次
                                    rotateImg(this,'right',canvas);
                                    break;
                            }
                        }

                        base64 = canvas.toDataURL("image/jpeg", 1);
                    }
                    $("#myImage").attr("src", base64);
                };
            };
            oReader.readAsDataURL(file);
        }
    }

    //对图片旋转处理 
    function rotateImg(img, direction,canvas) {
        //最小与最大旋转方向,图片旋转4次后回到原方向
        var min_step = 0;
        var max_step = 3;
        if (img == null)return;
        //img的高度和宽度不能在img元素隐藏后获取,否则会出错
        var height = img.height;
        var width = img.width;
        //var step = img.getAttribute('step');
        var step = 2;
        if (step == null) {
            step = min_step;
        }
        if (direction == 'right') {
            step++;
            //旋转到原位置,即超过最大值
            step > max_step && (step = min_step);
        } else {
            step--;
            step < min_step && (step = max_step);
        }
        //旋转角度以弧度值为参数
        var degree = step * 90 * Math.PI / 180;
        var ctx = canvas.getContext('2d');
        switch (step) {
            case 0:
                canvas.width = width;
                canvas.height = height;
                ctx.drawImage(img, 0, 0);
                break;
            case 1:
                canvas.width = height;
                canvas.height = width;
                ctx.rotate(degree);
                ctx.drawImage(img, 0, -height);
                break;
            case 2:
                canvas.width = width;
                canvas.height = height;
                ctx.rotate(degree);
                ctx.drawImage(img, -width, -height);
                break;
            case 3:
                canvas.width = height;
                canvas.height = width;
                ctx.rotate(degree);
                ctx.drawImage(img, -width, 0);
                break;
        }
    }

위 내용은 exfe.js와 canvas를 사용하여 모바일 IOS에서 사진 촬영 및 업로드 시 사진이 뒤집히는 문제 해결(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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