Сжатие изображений uri данных base64

Я создаю несколько диаграмм, которые затем отправляются на сервер для создания PDF. Эти данные могут стать большими.

вопрос

каков наилучший способ сжатия и отправки данных изображения на сервер

фон

диаграммы, которые я создаю, довольно сложны, чтобы сэкономить головную боль, все это преобразуется в холст, где генерируется uri данных base64. В настоящее время uri(ы) данных разносятся на сервер для обработки. Размещенная информация может получить довольно большой объем около 400-600kb каждый для небольшого графика и 12mb для самого большого графика.

графики диаграмм, которыми можно манипулировать/переупорядочены.

есть ли лучший способ сжатия этих строк перед отправкой на сервер?

исследования

некоторые вещи, которые я проверил out:

https://github.com/brunobar79/J-I-C/blob/master/src/JIC.js (не смотрите как вариант просто изменяется)

http://pastebin.com/MhJZBsqW (выглядит интересно)

но ссылок на внешние библиотеки, которые я не могу найти: C_H_Image Lib_MinifyJpeg

https://code.google.com/p/jslzjb/source/browse/trunk/Iuppiter.js?r=2 (похоже, это может работать, но зависит от декомпрессии на сервере сбоку)

4 ответов


возможно, сжатие строк-это решение для вас. Это преобразует данные в массивы байтов.

Существует несколько реализаций и алгоритмов вокруг, например

  • LZMA-JS автономная реализация JavaScript алгоритма сжатия цепи Лемпеля-Зива-Маркова (LZMA).

    my_lzma = new LZMA("./lzma_worker.js");
    my_lzma.compress("This is my compression test.", 1, function on_compress_complete(result) {
        console.log("Compressed: " + result);
        my_lzma.decompress(result, function on_decompress_complete(result) {
            console.log("Decompressed: " + result);
        }, function on_decompress_progress_update(percent) {
            console.log("Decompressing: " + (percent * 100) + "%");
        });
    }, function on_compress_progress_update(percent) {
        console.log("Compressing: " + (percent * 100) + "%");
    });
    
  • ЛЗ-строку: сжатие JavaScript, быстро!

    var str = "This is my compression test.";
    console.log("Size of sample is: " + str.length);
    var compressed = LZString.compress(str);
    console.log("Size of compressed sample is: " + compressed.length);
    str = LZString.decompress(compressed);
    console.log("Sample is: " + str);
    

Мне нужно было создать миниатюры из больших изображений. Я решил решить свою версию этой проблемы с помощью метода HTML5 Canvas. Я использую GWT, поэтому мой код:

//Scale to size
public static String scaleImage(Image image, int width, int height) {

    Canvas canvasTmp = Canvas.createIfSupported();
    Context2d context = canvasTmp.getContext2d();

    canvasTmp.setCoordinateSpaceWidth(width);
    canvasTmp.setCoordinateSpaceHeight(height);

    ImageElement imageElement = ImageElement.as(image.getElement());

    context.drawImage(imageElement, 0, 0, width, height);

    //Most browsers support an extra option for: toDataURL(mime type, quality) where quality = 0-1 double.
    //This is not available through this java library but might work with elemental version?
    String tempStr = canvasTmp.toDataUrl("image/jpeg");

    return tempStr;
}

Если вы используете JS, вы, вероятно, можете получить идею:

  • сделайте холст размером с желаемое выходное изображение
  • нарисуйте входное изображение на холсте в новом размере
  • вызов canvas.toDataURL ("мимический тип", качество)

вы можете использовать любой я думаю, что mime-тип, но для меня jpeg был самым маленьким и был сопоставим с результатами моей программы для настольных изображений.

мой GWT не позволил бы мне сделать параметр качества (и я не уверен на 100%, насколько широко он поддерживается в каких браузерах), но это было нормально, потому что полученные изображения были довольно маленькими. Если вы оставите MIME-тип пустым, он по умолчанию будет png, который в моем случае был 3-4x больше, чем jpeg.


Я, наконец, получил эту работу с довольно большими файлами.

для этого я использовал lz-string, как показано выше.

есть одна проблема, которая заключается в том, что отправка данных UTF-16 через ajax устарела, поэтому.. это не работает. Исправление заключается в преобразовании в UTF-16 и UTF-8.

вот код преобразования, который я использую. Я не уверен, что такое стандартный endian, кстати:

var UTF = {};

UTF.U16to8 = function(convertMe) {
var out = "";
  for(var i = 0; i < convertMe.length; i++) {
      var charCode = convertMe.charCodeAt(i);
      out += String.fromCharCode(~~(charCode/256));
      out += String.fromCharCode(charCode%256);
    }
  return out;
}

UTF.U8to16 = function(convertMe) {
  var out = ""
  for(var i = 0; i < convertMe.length; i += 2) {
    var charCode = convertMe.charCodeAt(i)*256;
    charCode += convertMe.charCodeAt(i+1);
    out += String.fromCharCode(charCode)
  }
  return out;
}

Если вы используете Node.Яш, этот код работает с обеих сторон. Если нет,вам придется написать свою собственную версию этих конвертеров для серверной части.

Фух! Что это был за день.


Это не очень удовлетворительный ответ, но, вероятно, нет библиотек, которые дают желаемый результат.

вы говорите, что изменение размера не является вариантом, но тогда что такое? Только сжатие без потерь? Строки Base64 уже представляют сжатый образ, я не думаю, что какие-либо библиотеки обеспечат сжатие без потерь.