이틀 전 업로드를 위해 이미지를 base64로 변환하는 기능을 만들었는데, 이미지의 base64가 너무 크면 요청 속도가 매우 느려지고 타임아웃이 심각하게 발생한다는 사실을 발견하여 이미지를 압축해볼까 하는 생각을 하게 되었습니다. 다음은 캔버스를 사용하여 이미지를 압축할 때 발생하는 몇 가지 함정입니다. 전체 코드는 기사 마지막 부분에 제공됩니다.
첫 번째 함정은 이미지를 압축할 때 이미지 자체의 너비와 높이를 구하지 못하고, 휴대폰에서 600*480의 고정된 너비와 높이를 준다는 점인데, 이미지를 업로드할 때 이미지가 뜹니다. 크기는 수 메가바이트이므로 문제 없습니다. 테스트 중 업로드된 사진이 모두 작은 사진이었는데, 압축된 사진이 완전히 표시되지 않고, 대부분이 압축 시 원본 너비를 고려하지 않았기 때문에 문제가 발생했습니다. 그리고 이미지의 높이.
두 번째 함정. 첫 번째 함정을 해결하는 방법은 이미지가 로드(onload)된 후 이미지 자체의 너비와 높이를 얻은 다음 이를 캔버스에 할당하는 것입니다. 함정은 이미지 로딩이 비동기적이라는 것입니다. 반환할 때 필요한 압축된 base64 대신 반환되는 내용이 정의되지 않을 수 있습니다. 여기서 해결 방법은 새 Promise를 생성한 다음, 결과를 Resolve()로 반환하고, .then()을 호출할 때 결과를 얻는 것입니다.
지식 포인트:miniImage.js
기본 비동기 함수 내보내기 miniSize(imgData, maxSize = 200*1024){ // const maxSize = 200 * 1024; if(imgData && imgData.files && imgData.files.size < maxSize) { return imgData.url; .log('----------------압축된 이미지------'); const canvas = document.createElement('canvas'); let img = new Image(); img.src = imgData.url; let ctx = canvas.getContext('2d'); return new Promise((resolve =>{ img.addEventListener( 'load', function(){ //그림의 원본 크기 let OriginWidth = this.width; let OriginHeight = this.height; // 최대 크기 제한 let maxWidth = 400, maxHeight = 400; // 대상 크기 let targetWidth = OriginWidth, targetHeight = OriginHeight; // 이미지 크기가 400x400 제한을 초과합니다. if (originWidth > maxWidth || OriginHeight > maxHeight) { if (originWidth / OriginHeight > maxWidth / maxHeight) { // 더 넓어지고 너비에 따라 크기가 제한됩니다. targetWidth = maxWidth; = Math.round(maxWidth * (originHeight / OriginWidth)); } else { targetHeight = maxHeight; targetWidth = Math.round(maxHeight * (originWidth / OriginHeight)) } } canvas.width = targetWidth; ctx.drawImage(img, 0, 0, targetWidth, targetHeight); canvas.toDataURL('image/png', 0.9); 해결(base64) }, })) }}
부르다:
test.js
onChangeImg = async (파일, 유형, 인덱스) => { let Previous = this.props.imagePicker.files; if(type === add) { let result = miniSize(files[files.length-1]) // .then()을 사용하여 wait result.then(res => { Previous.push({url: res}); }) }else if(type === Remove) { 이전.splice(index,1); } wait this.props.dispatch({ 유형: 'imagePicker/saveImage', 페이로드: { 파일: 이전 } }) }
위 내용은 이 기사의 전체 내용입니다. 모든 분들의 학습에 도움이 되기를 바랍니다. 또한 모든 분들이 VeVb Wulin Network를 지지해 주시길 바랍니다.