Результат html5 Canvas getImageData или toDataURL - Что занимает больше памяти?
Часть моего приложения включает редактирование фотографий html5, используя смесь стандартных 2d-контекстных холстов и webGL.
Во всяком случае, я сохраняю состояния "отменить", пока пользователь манипулирует своей фотографией. Все они хранятся в объекте Javascript как данные изображения base64.
Все работает отлично, а производительность хорошая.
Однако мне интересно, может ли хранить данные из getImageData меньше памяти или предложить лучшую производительность?
Итак, чтобы обобщить мой вопрос:
Что занимает больше места в памяти, base64 jpeg, сгенерированный toDataURL() или результат getImageData()? И есть ли различия в производительности между ними (относительно загрузки на холст и вытаскивания данных с холста)
Спасибо заранее.
Ответы
Ответ 1
Хороший вопрос! Я не уверен в истинных размерах самих объектов, и он должен отличаться от реализаций JS, но это не значит, что мы не можем сделать некоторые образованные предположения.
Сначала мы можем использовать функцию аппроксимации из этого вопроса: Размер объекта JavaScript
И сделаем пример: http://jsfiddle.net/g39uz/
Строка, возможно, составляет 80116 байт по сравнению с байтами ImageData 720056. Или около того.
Здесь порядок разницы здесь, и разница была бы еще более резкой, если бы изображение было простым. Стоит помнить, что представление Base64 может быть сжато (и оно есть). Пусть на какой-то момент взгляните на предел, используя пустой холст:
http://jsfiddle.net/g39uz/2/
На пустом холсте строка dataURL составляет всего лишь 1996 байт (или около того), но данные изображения, которые, конечно же, все еще покорно описывают каждый пиксель в кропотливой детали массива, по-прежнему составляют 720056.
Короче говоря, если вы его сохраняете, строка base64, вероятно, занимает меньше места. На порядок.
Ответ 2
getImageData() занимает больше памяти, чем toDataURL()
- ImageData - это массив пикселей, наибольшая информация об изображении, длина массива пикселей -
widthOfImage * heightOfImage * 4
, например, imageData, длина изображения с размерами 100 равна var imageDataArrayLenth = 100 * 100 * 4 = 40 000 (bytes);
- BLOB (JPG или PNG) - это imageData, сжатый по алгоритму jpg или png, размер которого может быть в 10 или 20 раз меньше, чем imageData (зависит от содержимого изображения).
- DataURL (BASE64) - это imageData, сжатый в JPG или PNG, затем преобразованный в строку, и эта строка на 37% больше (информация), чем BLOB.
Вывод: лучше использовать BLOB (информация).
//Example of using blob with objectURL
var canvas = document.getElementById("canvas");
canvas.toBlob((blob) => {
let img = new Image();
img.onload = () => URL.revokeObjectURL(img.src); // no longer need to read the blob so it revoked
img.src = URL.createObjectURL(blob);
document.body.appendChild(img);
});
Ответ 3
Я только что прошел через этот день... метод getImageData возвращает объект изображения, в котором фактические данные хранятся в файле uint8array... вам нужно преобразовать данные в то, что может управлять ваша база данных, а просто не стоит того, конечный результат намного больше, чем метод toDataURL
Его также очень просто вернуть toDataURL base64 строку обратно на холст... вы просто создаете новое изображение и передаете src строку base64