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.4 kb, если вы затем сохраните изображение, которое выводится, вы увидите, что это 10kb. Разница более заметна при более детальных изображениях. Если вы установите для качества toDataUrl значение 1, то изображение 17kb.

Я также использую FireFox 10 для этого, при использовании Chrome размеры изображения все еще больше, но не на столько.

3 ответов


строка, возвращаемая 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 из загрузки файла также отличаются:

тестовый случай: http://jsfiddle.net/Fkykx/

<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>

размер изображения определяется в основном качеством энкодера, встроенного в браузер. Она имеет очень мало общего с размером исходного изображения. Как только вы нарисуете что-нибудь на canvas все, что у вас есть, это пиксели, у вас больше нет исходного изображения. toDataURL не восстанавливает магически изображение, которое было нарисовано на canvas. Если вам нужен файл того же размера, что и исходное изображение: используйте исходное изображение.


похоже, кириллойд и Роб прибили его. У меня тоже была эта проблема, и, похоже, это комбо:

  • dataURL использует кодировку base64, которая делает его вокруг 1.37 X больше
  • каждый браузер обрабатывает функцию toDataURL по-разному

размер закодированного изображения base64

я протестировал свой генератор миниатюр в win8.1 firefox и chrome и получил размер строки dataURL:

  • в Firefox = 3.72 КБ
  • chrome = 3,24 КБ

мое исходное изображение при преобразовании в dataURL пошло от 32kB до 45kB.

Я думаю, что часть base64 является большим фактором, поэтому я думаю, что мой план теперь заключается в преобразовании dataURL обратно в двоичный массив байтов, прежде чем я сохраню его на сервере (вероятно, на стороне клиента, потому что мой сервер ленивый).