Подтвердить что ты не робот

Сжатие базовых изображений данных uri64

Проблема

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

Вопрос

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

Фон

Графики, которые я создаю, довольно сложны, чтобы сохранить головную боль, все это преобразуется в холст, где генерируется urics данных base64. В настоящее время данные uri отправляются на сервер для обработки обработки. Добавленная информация может быть довольно большой на уровне около 400-600 тыс. Каждая для небольшой диаграммы и 12 МБ для самой большой диаграммы.

Графики представляют собой организационные диаграммы, которые можно манипулировать/переупорядочивать.

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

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

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

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 (похоже, что это может работать, но зависит от декомпрессии на стороне сервера)

4b9b3361

Ответ 1

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

Например, существует множество реализаций и алгоритмов.

  • 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) + "%");
    });
    
  • lz-string: сжатие 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);
    

Ответ 2

Мне нужно было создавать эскизы из более крупных изображений. Я решил решить мою версию этой проблемы с помощью технологии Canvas HTML5. Я использую 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-type", качество)

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

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

Ответ 3

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

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

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

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

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.js, этот код работает с обеих сторон. Если нет, вам придется написать свою версию этих конвертеров для серверной части.

Уф! Что это за день.

Ответ 4

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

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