얼마 전 회사에서 Vue를 이용해 웹앱을 개발하던 중, 사진을 찍거나 휴대폰 앨범에 전화를 걸어 사진을 표시한 뒤 불과 반년 만에 서버에 업로드하는 사용자를 만났습니다. 프론트엔드 작업을 하면서 나는 함정으로 가득 찬 길을 시작했습니다. 아래에서 내가 겪었던 함정에 대해 이야기하겠습니다.
모바일 사진첩 불러오기
iOS는 문제 없지만 안드로이드폰은 정말 함정이 많아서 검색해봤습니다. 온라인에서는 휴대전화가 작동하지 않는 경우도 있습니다. 사진 앨범만 조정할 수 있지만 카메라는 조정할 수 없거나, 카메라만 조정할 수 있지만 사진 앨범은 조정할 수 없습니다.
사진을 받은 후 사진 앨범을 호출하고 인터페이스에 렌더링하면 iOS가 다시 나타납니다. 문제는 카메라로 찍은 사진이 90도 회전되거나, 애플의 일반 사진이 안드로이드에서 표시될 때 90도 회전되는 것입니다. 휴대폰 및 Apple에서 일반적으로 사용되는 일부 사진은 배경에서 왜곡됩니다. iOS 개발자로서 저는 이것을 여러 번 조사한 끝에 Apple의 카메라가 비뚤어져 있다는 결론에 도달했습니다.
이미지가 렌더링된 후 브라우저가 충돌합니다. 특히 WeChat에서는 WeChat에 무언가를 업로드할 때 모든 종류의 문제가 발생합니다.
처음에는 파일 업로드 형태로 진행됐는데, 나중에 테스트 결과 많은 안드로이드폰이 성공적으로 업로드되지 않는 것으로 나타났습니다. 너무 많이 말하면 눈물이 난다. 너무 많이 말하지 않으면 본론으로 들어가자!
제 솔루션을 정리하자면, 아직 저처럼 초보인 분들에게 도움이 되었으면 좋겠습니다
h5를 사용하여 사진첩을 호출하는 것은 웹페이지에서 한 문장으로 호출하는 것이지만, 사진첩과 카메라를 모두 조정하려면 이렇게 작성해야 합니다(정말 오랫동안 확인했습니다)
<form id="uploadForm" enctype="multipart/form-data"> <input class="upload-open-photo" accept="image/*" type="file" id="filechooser" v-on:change="btnUploadFile($event)"/> </form>
이미지 렌더링은 캔버스를 사용했고, 휴대폰 촬영 방향(즉, 휴대폰을 들고 있는지 여부)을 얻기 위해 EXIF.js라는 플러그인을 사용했습니다. 사진을 찍을 때 수직 또는 수평) 장치를 판단합니다. iOS 기기 중 3개를 방향으로 회전하고 캔버스를 사용하여 캔버스에 그립니다.
btnUploadFile(e){ //获取图片 var self = this; var filechooser = document.getElementById('filechooser'); var previewer = document.getElementById('previewer'); var that = e.target; var files = that.files; var file = files[0]; //判断拍摄方向, EXIF.getData(file,function(){ self.orientation=EXIF.getTag(this,'Orientation'); }); self.fileData = file; // 接受 jpeg, jpg, png 类型的图片 if (!/\/(?:jpeg|jpg|png)/i.test(file.type)){ return; } var reader = new FileReader(); reader.onload = function() { var result = this.result; var img = new Image(); //进行图片的渲染 img.onload = function() { //图片旋转压缩处理后的base64 var compressedDataUrl =self.compress(img,self.fileData.type); //渲染到img标签上 self.toPreviewer(compressedDataUrl); img = null; }; img.src = result; }; reader.readAsDataURL(self.fileData); },
사진을 렌더링하려면 사진을 회전해야 할 뿐만 아니라 압축도 해야 합니다. 현재 카메라 픽셀이 너무 높기 때문에 고화질 사진을 사용하면 브라우저가 중단될 수 있습니다. WeChat 브라우저에서만 적용하면 됩니다. WeChat jssdk에서 사진 앨범을 호출하는 방법을 참조하면 사진 왜곡 및 충돌 문제가 발생하지 않습니다. 물론 WeChat만 하는 것이 아니라 캔버스
(mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html)
//对图片进行旋转,压缩的方法,最终返回base64 渲染给img标签的src compress(img, fileType) { var degree=0,drawWidth,drawHeight,width,height; drawWidth=img.width; drawHeight=img.height; //以下改变一下图片大小 var maxSide = Math.max(drawWidth, drawHeight); if (maxSide > 1024) { var minSide = Math.min(drawWidth, drawHeight); minSide = minSide / maxSide * 1024; maxSide = 1024; if (drawWidth > drawHeight) { drawWidth = maxSide; drawHeight = minSide; } else { drawWidth = minSide; drawHeight = maxSide; } } var canvas=document.createElement('canvas'); canvas.width=width=drawWidth; canvas.height=height=drawHeight; var context=canvas.getContext('2d'); //判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式 if($.device.ios){ switch(this.orientation){ //iphone横屏拍摄,此时home键在左侧 case 3: degree=180; drawWidth=-width; drawHeight=-height; break; //iphone竖屏拍摄,此时home键在下方(正常拿手机的方向) case 6: canvas.width=height; canvas.height=width; degree=90; drawWidth=width; drawHeight=-height; break; //iphone竖屏拍摄,此时home键在上方 case 8: canvas.width=height; canvas.height=width; degree=270; drawWidth=-width; drawHeight=height; break; } } //使用canvas旋转校正 context.rotate(degree*Math.PI/180); context.drawImage(img,0,0,drawWidth,drawHeight); // 压缩0.5就是压缩百分之50 var base64data = canvas.toDataURL(fileType, 0.5); canvas = context = null; this.urlbase = base64data; return base64data; },
를 사용하여 압축해야 하며 마지막으로 base64 렌더링을 src
toPreviewer(dataUrl) { previewer.src = dataUrl; },
로 가져옵니다. Base64는 백그라운드에서 제공됩니다. base64를 통해 이미지를 업로드하는 인터페이스가 제공됩니다. base64는 우리가 얻은 base64가 회전되고 압축된 이미지의 base64이므로 이미지를 서버에 업로드하거나 다른 위치에서 표시할 때 다른 페이지에서 이 이미지를 표시하려는 경우 회전되고 압축됩니다. , 회전과 압축 과정은 생략하겠습니다! 사실 일부 Android 기기에서는 파일 전송을 통한 사진 업로드가 작동하지 않는 이유를 아직도 모르겠습니다. 하지만 base64 업로드 방법을 성공적으로 변경한 후에는 더 이상 취업 걱정을 할 필요가 없습니다.
결론적으로 보면 제가 프론트엔드 경험이 부족해서 많은 함정을 밟은 것 같아요!
[관련 추천]
위 내용은 html5를 사용하여 모바일 단말기에서 사진을 처리하는 튜토리얼 예의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!