問題
PDFを作成するためにサーバーに送信される複数のグラフを作成しています。このデータは大きくなる可能性があります。
質問
画像データを圧縮してサーバーに送信する最良の方法は何ですか
背景
私が作成しているチャートはかなり複雑です。頭痛を省くために、このすべてがbase64データuriが生成されるキャンバスに変換されます。現在、データuriは、処理を処理するためにサーバーに送信されます。投稿された情報は、小さなチャートでは約400〜600 kb、最大のチャートでは12 mbとかなり大きくなります。
チャートは、操作/並べ替えが可能な組織チャートです。
これらの文字列をサーバーに送り返す前に圧縮するより良い方法はありますか?
研究
私がチェックアウトしたいくつかのこと:
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 (これは機能するように見えますが、サーバー側の解凍に依存しています)
たぶん文字列圧縮があなたのための解決策です。これにより、データがバイト配列に変換されます。
たとえば、複数の実装とアルゴリズムがあります
LZMA-JSLempel-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);
大きな画像からサムネイルを生成する必要がありました。この問題の私のバージョンを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を使用している場合、おそらくアイデアを得ることができます。
私が思うに任意のMIMEタイプを使用できますが、私にとってはjpegが最小で、私のデスクトップイメージプログラムの結果に匹敵しました。
私のGWTは品質パラメーターを許可しませんでした(そして、どのブラウザーでどれだけ広くサポートされているかは100%わかりません)。 mime-typeを空白のままにすると、デフォルトではpngになり、私の場合はjpegよりも3〜4倍大きくなります。
かなり大きなファイルでこれが機能するようになりました。
それをするために、lz-string
、 上記のように
ただし、1つの問題があります。これは、 ajaxを介したUTF-16データの送信は非推奨 であるため、機能しません。修正は、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を使用している場合、このコードは両側で機能します。そうでない場合は、サーバー側にこれらのコンバーターの独自のバージョンを作成する必要があります。
ふう!これはなんて日だった。
これはあまり満足のいく答えではありませんが、おそらくあなたが望む結果を与えるライブラリはありません。
サイズ変更はオプションではないと言いますが、それでは何ですか?ロスレス圧縮のみ? Base64文字列はすでに圧縮されたイメージを表しているため、どのライブラリもロスレス圧縮を提供するとは思わない。