压缩base64数据uri图像

时间:2014-03-11 14:58:41

标签: javascript html post data-uri

问题

我正在创建多个图表,然后将这些图表发送到服务器以创建PDF。这些数据可能会变大。

问题

将图像数据压缩并发送到服务器的最佳方法是什么

背景

我正在创建的图表相当复杂,为了省去自己的头痛,所有这些都转换为生成base64数据uri的画布。目前,数据uri被发布到服务器以处理处理。对于小图表,发布信息可以相当大,每个大约400-600kb,对于最大图表,大小为12mb。

图表是可以操作/重新排序的组织结构图。

在将这些字符串发送回服务器之前是否有更好的压缩方法?

研究

我看过的一些事情:

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 个答案:

答案 0 :(得分:35)

也许字符串压缩是您的解决方案。这会将数据转换为字节数组。

有多种实现和算法,例如

  • LZMA-JS Lempel-Ziv-Markov链(LZMA)压缩算法的独立JavaScript实现。

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

答案 1 :(得分:8)

我需要从较大的图片生成缩略图。我决定使用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-type”,quality)

你可以使用我认为的任何mime类型,但对我来说,jpeg是最小的,并且与我的桌面图像程序的结果相当。

我的GWT不会让我做质量参数(并且我不是100%确定它在哪些浏览器中受到广泛支持),但这没关系,因为生成的图像非常小。如果你将mime-type留空,则默认为png,在我的情况下,它比jpeg大3-4倍。

答案 2 :(得分:3)

我终于使用了相当大的文件。

为此,我使用了lz-stringas shown above.

但是有一个问题,即sending UTF-16 data via ajax is deprecated,所以..它不起作用。解决方法是转换为UTF-16和UTF-8。

这是我正在使用的转换代码。我不确定标准字节序是什么,顺便说一下:

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,则此代码适用于双方。如果没有,您将必须为服务器端编写自己的这些转换器版本。

唷!这是多么的一天。

答案 3 :(得分:0)

这不是一个令人满意的答案,但可能没有图书馆可以提供你想要的结果。

你说调整大小不是一种选择,但那么,是什么?只有无损压缩? Base64字符串已经表示压缩图像,我认为任何库都不会提供无损压缩。