Blob: невозможно декодировать изображение по URL
В настоящее время я делаю надстройку Word Web. Это использует Internet Explorer в качестве движка. Моя надстройка должна загрузить несколько выбранных изображений с компьютера пользователя.
Поскольку некоторые из выбранных изображений могут быть довольно большими, я изменяю их размер с помощью HTML5 canvas. Это мой код для изменения размера:
function makeSmallImage(imageContainer, retries)
{
if (retries === undefined)
retries = 0;
console.log('Resizing image..')
return new Promise(function (resolve, reject)
{
img = img || new Image();
img.onload = function ()
{
// calculate new size
var width = 200;
var height = Math.floor((width / img.naturalWidth) * img.naturalHeight);
console.log('new size', width, height);
try
{
// create an off-screen canvas
canvas = canvas || document.createElement('canvas'),
ctx = ctx || canvas.getContext('2d');
// antialiasing
ctx.imageSmoothingEnabled = true;
// set its dimension to target size
canvas.width = width;
canvas.height = height;
// draw source image into the off-screen canvas:
ctx.drawImage(img, 0, 0, width, height);
// clean up
imageContainer.largeData = undefined;
if (img.src.substr(0, 4) === 'blob')
URL.revokeObjectURL(img.src);
img.src = '';
// encode image to data-uri with base64 version of compressed image
var newDataUri = canvas.toDataURL();
ctx.clearRect(0, 0, canvas.width, canvas.height);
console.log('Image resized!');
imageContainer.resizedData = newDataUri;
resolve(imageContainer);
}
catch (e)
{
if (img.src !== undefined && img.src.substr(0, 4) === 'blob')
URL.revokeObjectURL(img.src);
console.log(e);
if (e.message === "Unspecified error." && retries < 5)
{
setTimeout(function (imgContainer, re)
{
makeSmallImage(imgContainer, re).then(resolve).catch(reject);
}, 2000, imageContainer, retries + 1);
}
else
reject('There was an error while trying to resize one of the images!');
}
};
try
{
var blob = new Blob([imageContainer.largeData]);
img.src = URL.createObjectURL(blob);
} catch (e)
{
reject(e);
}
});
}
"img", "canvas" и "ctx" являются глобальными переменными, поэтому одни и те же элементы используются повторно. 'imgcontainer.largedata' является массивом uint8array. Чтобы избежать большого использования памяти, я загружаю и изменяю размеры изображения одно за другим.
Несмотря на это, после загрузки, например, 120 изображений размером 10 Мб, может случиться так, что я получу ошибку:
Невозможно декодировать изображение по URL-адресу: 'blob:D5EFA3E0-EDE2-47E8-A91E-EAEAD97324F6'
Затем я получаю исключение "Unspecified error", в котором не так много информации. Теперь вы можете увидеть в коде, что я добавил небольшой механизм, чтобы повторить попытку, но все новые попытки терпят неудачу.
Я думаю, причина в том, что Internet Explorer использует слишком много памяти. Я думаю, что некоторые ресурсы не очищаются правильно, но я не могу обнаружить утечку памяти в моем коде здесь (если вы можете, пожалуйста, дайте мне знать).
У кого-нибудь есть представление о том, как я могу это исправить или обойти это?
1 ответ
Если вы попытаетесь изменить размер изображения, почему бы не использовать офисные API напрямую? Вы можете сначала получить изображения, а затем использовать свойство высоты / ширины, чтобы изменить его размер, например:
image1.height = 5; image1.width = 5;