сценарий спроса
Изображение загружается в фоновом режиме операции, и страница генерирует QR-код апплета, который объединяется с изображением, загруженным операцией, для формирования большого изображения, которое используется для обмена и распространения страницы в кругу. друзей.
Реализовать идеи
1. Загрузка фонового изображения
Загрузка фонового изображения, вызов интерфейса для загрузки файла на платформу oss и создание ссылки на фоновое изображение.
2. Сгенерируйте QR-код апплета для страницы
Вызовите интерфейс генерации QR-кода апплета, чтобы сгенерировать QR-код страницы. За подробностями обращайтесь к официальной документации программы Mini:Developers.WeChat.QQ.com/mini программа…. При звонке обратите внимание, что длина параметра ограничена, если параметр слишком длинный, генерация QR-кода не удастся. Наш подход заключается в том, чтобы согласовать набор правил сопоставления URL-адресов с апплетом и сопоставить соответствующую страницу h5 с помощью определенных параметров.
3. Напишите html-код для скриншота
Заполните HTML-код, необходимый для создания снимков экрана, включая фоновое изображение (фоновое изображение, загруженное операцией), QR-код апплета страницы и другие элементы.
4. Вызовите html2canvas, чтобы получить снимок экрана
После поиска в Интернете функция скриншота может быть достигнута с помощью плагина html2canvas Код выглядит следующим образом:
// index.js
import html2canvas from 'html2canvas';
html2canvas(this.$refs.shareImgElem, {
useCORS: true,
backgroundColor: null
})
.then(canvas => {
const dataUrl = canvas.toDataURL('images/jpg');
// 第一步:将dataUrl转换成Blob
const blob = this.base64ToBlob(dataUrl);
// 第二步:上传分享图
this.uploadShareImg(blob);
})
// index.vue
// 需要截图的html代码
<div ref="shareImgElem">....</div>
// 截图图片的链接
<img :src="imgUrl" />
В этот момент я подумал, что сохранение dataUrl идеально решит это требование. Однако дело в том, что base64-битное изображение, сгенерированное скриншотом, представляет собой белый экран. Я также проверил использование html2canvas в Интернете и определил, что метод вызова был правильным, но скриншот был пустым. Позже я проверил причину, начал с самой простой демонстрации и, наконец, нашел причину белого экрана, которая резюмируется следующим образом.
5. Сводка проблем с белым экраном на снимках экрана
5.1 Междоменная проблема изображения
Если код снимка экрана содержит изображения, для изображений необходимо разрешить междоменный доступ, иначе js не сможет прочитать информацию об изображении. Если изображение размещено на cdn, cdn необходимо установить настройки, связанные с cors, то есть в заголовке ответа на запрос изображения необходимо установить Access-Control-Allow-Origin: *
Изображения нашей компании загружаются на платформу Ali oss, а междоменная информация, установленная в корзине в oss, предназначена для контроля источника доменного имени при загрузке изображений. И нам нужно настроить изображение как междоменное при чтении, а изображение хранится на cdn, поэтому свяжитесь с эксплуатацией и обслуживанием и добавьте информацию о междоменном в конфигурации cdn.
5.2 Элементы скриншота находятся в пределах видимости экрана
После добавления междоменной информации в заголовок ответа на запрос изображения снимок экрана по-прежнему остается пустым экраном, а затем продолжают искать причину и, наконец, обнаружили, что когда элемент снимка экрана находится в пределах видимого диапазона первого экрана, правильный снимок экрана может быть сгенерирован. Получается, что в процессе генерации скриншота, если мышь прокручивается, сгенерированный скриншот будет смещаться на холсте. Есть две операции для решения этой проблемы:
5.2.1 Заранее поместите элемент скриншота вверху страницы, в пределах области экрана.
5.2.2 Во время создания скриншота прокрутка страницы отключена. код показывает, как показано ниже:
dom.setScrollTop(0); // 先滚动到最顶部
document.documentElement.style.position = 'fixed';
5.2.3 После создания скриншота страница возобновляет прокрутку, код выглядит следующим образом:
document.documentElement.style.position = '';
В это время наконец появился скриншот. Однако в настоящее время на снимке экрана используется кодировка base64. Хранение такой большой строки символов в фоновом режиме нецелесообразно. В настоящее время рассмотрите возможность преобразования символов base64 в поток двоичных данных большого двоичного объекта и загрузите его в oss.
6. Загрузить скриншот
6.1 Преобразование символов, закодированных в base64, в объекты двоичных данных blob.
Код преобразования выглядит следующим образом:
// base64转换成blob数据
base64ToBlob(dataUrl, type) {
var arr = dataUrl.split(',');
var mime = arr[0].match(/:(.*?);/)[1] || type;
// 去掉url的头,并转化为byte
var bytes = window.atob(arr[1]);
// 处理异常,将ascii码小于0的转换为大于0
var ab = new ArrayBuffer(bytes.length);
// 生成视图(直接针对内存):8位无符号整数,长度1个字节
var ia = new Uint8Array(ab);
for (var i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], {
type: mime
});
}
6.2 Загрузка потока двоичных данных BLOB-объектов на платформу OSS
код показывает, как показано ниже:
// 上传Blob二进制数据
uploadBlob(fileName, blob) {
return new Promise((resolve, reject) => {
async function putBlob() {
try {
let result = await ossClient.put(fileName, blob);
result.imgUrl = `${CDN_IMAGE_DOMAIN}/${result.name}`;
resolve(result);
} catch (e) {
reject(e);
}
}
putBlob();
});
}
// 上传分享大图
uploadShareImg(blob) {
const fileName = `web/activityms/share_big_img_${Date.parse(new Date())}.jpg`;
this
.uploadBlob(fileName, blob)
.then(res => {
this.imgUrl = res.imgUrl;
this.$message.success('朋友圈分享大图上传成功!');
});
}
На этом этапе снимок экрана успешно создается и загружается на платформу oss, а путь к изображению возвращается.