Canvas toDataUrl увеличивает размер файла изображения - PullRequest
17 голосов
/ 19 марта 2012

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

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

Ответы [ 3 ]

13 голосов
/ 20 марта 2012

Строка, возвращаемая методом 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

Метод получения data-URI не имеет значения, для проверки того, что data-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>
4 голосов
/ 19 марта 2012

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

2 голосов
/ 03 февраля 2015

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

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

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

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

  • firefox= 3,72 КБ
  • хром = 3,24 КБ

Мое исходное изображение при преобразовании в dataURL изменилось с 32 КБ до 45 КБ.

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

...