I use the html2canvas library to capture screenshots by passing in a className and saving the image file as a blob. However, when the image is saved or downloaded, there is an issue with elements that have background-image: url(data:image/svg+xml;base64,...)
(SVG image), but PNG images are not affected. I am using html2canvas version 1.4.1.
function captureImg(className) {
const bannerElement = document.querySelector('.' + className);
return html2canvas(bannerElement, {
scale: 2,
backgroundColor: null,
}).then(canvas => {
return new Promise((resolve, reject) => {
canvas.toBlob(blob => {
if (blob) {
const file = new File([blob], 'banner-screenshot.png', {
type: 'image/png'
});
resolve(file);
} else {
reject(new Error('Failed to convert canvas to blob'));
}
}, 'image/png');
});
}).finally(() => {
}).catch(error => {
console.error('Error capturing the banner:', error);
});
}
function captureImgNow() {
captureImg('basic-box').then(file =\> {
const formData = new FormData();
formData.append('file_img', file);
formData.append('error_now', error_now);
formData.append('user_learn_id', user_learn_id);
formData.append('lesson_id', lesson_id);
formData.append('detail_id', detail_id);
formData.append('type', 'wrong');
formData.append('max_error', max_error);
$.ajax({
url: '/save-user-note-exam-failed',
method: 'POST',
contentType: 'application/json',
data: formData,
contentType: false,
processData: false,
cache: false,
success: function (response) {
console.log('captureImgNow');
},
error: function (xhr) {
}
});
})
}
This is the image I want This is result This this CSS
I tried dom-to-image, but the speed is quite slow and not suitable for my project.
<img width="200px" height="200px" style="z-index: 1000; position: absolute; top: 50%; left: 50%;" src="<%= item.image_background_gray == null ? item.image_background : item.image_background_gray%>" alt="test">
This is an image test This is the result test
You can try writing this code
async function convertSvgUrlToCanvas(url) {
const response = await fetch(url);
const svgText = await response.text();
const svgElement = new DOMParser().parseFromString(svgText, 'image/svg+xml').documentElement;
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const img = new Image();
const svgData = `data:image/svg+xml;base64,${btoa(new XMLSerializer().serializeToString(svgElement))}`;
img.src = svgData;
return new Promise((resolve) => {
img.onload = () => {
canvas.width = img.width;
canvas.height = img.height;
ctx.drawImage(img, 0, 0);
resolve(canvas);
};
});
}
async function handleSvgBackgrounds(element) {
const elements = element.querySelectorAll('*');
for (const el of elements) {
const style = window.getComputedStyle(el);
const backgroundImage = style.getPropertyValue('background-image');
if (backgroundImage.startsWith('url("data:image/svg+xml')) {
const urlMatch = backgroundImage.match(/url\("(.+)"\)/);
if (urlMatch) {
const svgUrl = urlMatch[1];
const svgCanvas = await convertSvgUrlToCanvas(svgUrl);
// Replace the SVG background with the canvas image
el.style.backgroundImage = `url(${svgCanvas.toDataURL()})`;
}
}
}
}
async function captureImg(className) {
const bannerElement = document.querySelector('.' + className);
await handleSvgBackgrounds(bannerElement);
return html2canvas(bannerElement, {
scale: 2,
backgroundColor: null,
}).then(canvas => {
return new Promise((resolve, reject) => {
canvas.toBlob(blob => {
if (blob) {
const file = new File([blob], 'banner-screenshot.png', {
type: 'image/png'
});
resolve(file);
} else {
reject(new Error('Failed to convert canvas to blob'));
}
}, 'image/png');
});
}).catch(error => {
console.error('Error capturing the banner:', error);
});
}
function captureImgNow() {
captureImg('basic-box').then(file => {
const formData = new FormData();
formData.append('file_img', file);
formData.append('error_now', error_now);
formData.append('user_learn_id', user_learn_id);
formData.append('lesson_id', lesson_id);
formData.append('detail_id', detail_id);
formData.append('type', 'wrong');
formData.append('max_error', max_error);
$.ajax({
url: '/save-user-note-exam-failed',
method: 'POST',
data: formData,
contentType: false,
processData: false,
cache: false,
success: function (response) {
console.log('captureImgNow');
},
error: function (xhr) {
console.error('Error uploading the image:', xhr);
}
});
}).catch(error => {
console.error('Error in captureImgNow:', error);
});
}