Два дня назад я создал функцию для преобразования изображений в base64 для загрузки. Я обнаружил, что если base64 изображения слишком велик, запрос станет очень медленным и серьезно истечет, поэтому я подумал о сжатии изображения. перед загрузкой, а затем загрузить его в фоновый режим, что может значительно повысить эффективность. Вот некоторые подводные камни, с которыми можно столкнуться при использовании холста для сжатия изображений. Полный код будет приведен в конце статьи.
Первый подводный камень - при сжатии изображения не получается ширина и высота самого изображения, а дается фиксированная ширина и высота 600*480. Потому что это на мобильном телефоне, при загрузке изображения. имеет размер несколько мегабайт, так что это не проблема. Проблема возникла при изменении аватара. Все загруженные во время теста изображения были маленькими, а затем сжатые изображения отображались не полностью, и большинство из них были пустыми. Это связано с тем, что при сжатии не учитывалась исходная ширина. и высота изображения.
Второй подводный камень. Способ решения первого подводного камня состоит в том, чтобы получить ширину и высоту самого изображения после его загрузки (onload), а затем присвоить его холсту. Однако эта операция выполняется таким образом. Ошибка заключается в том, что загрузка изображения является асинхронной, когда вы возвращаетесь, то, что возвращается, может быть неопределенным вместо нужного вам сжатого base64. Решение здесь состоит в том, чтобы создать новое обещание, затем вернуть результатsolve() и получить результат при вызове .then().
Очки знаний:miniImage.js
экспортировать асинхронную функцию по умолчанию miniSize(imgData, maxSize = 200*1024){ // const maxSize = 200 * 1024; if(imgData && imgData.files && imgData.files.size < maxSize) { return imgData.url }else{ console; .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)); ctx.drawImage(img, 0, 0, targetWidth, targetHeight); пусть base64 =; Canvas.toDataURL('image/png', 0,9); разрешить (base64 }, false })) }});
Вызов:
test.js
onChangeImg = async (files, type, index) => { let previous = this.props.imagePicker.files; if(type === add) { let result = miniSize(files[files.length-1]); Используйте .then() для вызова await result.then(res => { previous.push({url: res}); }); else if(type === delete) { previous.splice(index,1); } await this.props.dispatch({ type: 'imagePicker/saveImage', payload: { files: previous } }) }
Выше приведено все содержание этой статьи. Я надеюсь, что она будет полезна для изучения всеми. Я также надеюсь, что все поддержат сеть VeVb Wulin.