Canvas toDataUrl увеличивает размер файла изображения
При использовании toDataUrl() для установки источника тега изображения я обнаружил, что изображение при сохранении намного больше исходного изображения.
В приведенном ниже примере я не указываю второй параметр для функции toDataUrl, поэтому используется качество по умолчанию. Это приводит к значительному увеличению размера оригинального изображения. При задании 1 для полного качества созданное изображение еще больше.
Кто-нибудь знает, почему это происходит или как я могу это остановить?
// create image
var image = document.createElement('img');
// set src using remote image location
image.src = 'test.jpg';
// wait til it has loaded
image.onload = function (){
// set up variables
var fWidth = image.width;
var fHeight = image.height;
// create canvas
var canvas = document.createElement('canvas');
canvas.id = 'canvas';
canvas.width = fWidth;
canvas.height = fHeight;
var context = canvas.getContext('2d');
// draw image to canvas
context.drawImage(image, 0, 0, fWidth, fHeight, 0, 0, fWidth, fHeight);
// get data url
dataUrl = canvas.toDataURL('image/jpeg');
// this image when saved is much larger than the image loaded in
document.write('<img src="' + dataUrl + '" />');
}
Спасибо: D
Вот пример, к сожалению, образ не может быть перекрестным доменом, поэтому мне нужно просто вытащить одно из изображений jsfiddle.
http://jsfiddle.net/ptSUd/
Изображение будет 7.4kb, если вы затем сохраните изображение, которое будет выведено, вы увидите, что оно равно 10kb. Разница более заметна с более подробными изображениями. Если вы установите для качества toDataUrl значение 1, тогда изображение будет 17kb.
Я также использую FireFox 10 для этого, при использовании Chrome размеры изображений еще больше, но не так сильно.
Ответы
Ответ 1
Строка, возвращаемая методом toDataURL()
, не представляет исходных данных.
Я только что провел несколько обширных тестов, которые показали, что созданный URL-адрес данных зависит от браузера (а не от операционной системы).
Environment - md5 sum - file size
Original file - c9eaf8f2aeb1b383ff2f1c68c0ae1085 - 4776 bytes
WinXP Chrome 17.0.963.79 - 94913afdaba3421da6ddad642132354a - 7702 bytes
Linux Chrome 17.0.963.79 - 94913afdaba3421da6ddad642132354a - 7702 bytes
Linux Firefox 10.0.2 - 4f184006e00a44f6f2dae7ba3982895e - 3909 bytes
Метод получения URI данных не имеет значения, следующий фрагмент был использован для проверки того, что URI данных из загрузки файла также отличается:
<input type="file" id="file"><script>
document.getElementById('file').onchange=function() {
var filereader = new FileReader();
filereader.onload = function(event) {
var img = new Image();
img.onload = function() {
var c = document.createElement('canvas'); // Create canvas
c.width = img.width;
c.height = img.height; c.getContext('2d').drawImage(img,0,0,img.width,img.height);
var toAppend = new Image;
toAppend.title = 'Imported via upload, drawn in a canvas';
toAppend.src = c.toDataURL('image/png');
document.body.appendChild(toAppend);
}
img.src = event.target.result; // Set src from upload, original byte sequence
img.title = 'Imported via file upload';
document.body.appendChild(img);
};
filereader.readAsDataURL(this.files[0]);
}
</script>
Ответ 2
Размер изображения определяется в основном качеством кодировщика, встроенного в браузер. Он имеет очень мало общего с размером исходного изображения. Когда вы нарисуете что-либо на canvas
все, что у вас есть пиксели, у вас больше нет исходного изображения. toDataURL
не волшебным образом восстанавливает изображение, которое было нарисовано на canvas
. Если вам нужен файл с тем же размером, что и исходное изображение: используйте исходное изображение.
Ответ 3
Похож на кириллоид, и Роб прибил его. У меня тоже была эта проблема, и она кажется комбо:
- dataURL использует кодировку base64, которая делает ее вокруг 1.37 X больше
- каждый браузер обрабатывает функцию toDataURL по-разному
размер закодированного изображения base64
Я проверил мой генератор миниатюр в win8.1 firefox и chrome и получил размеры строки данныхURL:
- firefox = 3.72kB
- chrome = 3.24kB
Мое исходное изображение при преобразовании в dataURL перешло от 32 кБ до 45 КБ.
Я думаю, что часть base64 является более крупным фактором, поэтому я предполагаю, что теперь мой план состоит в том, чтобы преобразовать dataURL обратно в бинарный массив байтов, прежде чем я сохраню его на сервере (возможно, на стороне клиента, потому что мой сервер ленив).