私は現在、ionicとcordovaを使用してモバイルデバイス(AndroidとiPhone)でアプリケーションを開発しています。写真を編集したいのですが。私はそれを行うためにfabric.jsライブラリを使用します。 Fabric.jsは、画像やその他のアイテムをキャンバスに変換します。次に、キャンバスに画像(ステッカー)を追加し、画像(dataURL)としてエクスポートします。したがって、キャンバスのサイズは品質要因であるため非常に重要です(小さなキャンバスに基づいて画像をエクスポートすると、品質が低下します)。キャンバスのサイズは約607 * 1080ピクセルです(写真を撮ったデバイスによって異なります)。品質を落とさずに画面に合わせたい(以下で説明するように、品質を落とさずにキャンバスのサイズを変更することはできません)。
私は3つのアイデアを試しましたが、誰もうまくいきませんでした。
それを行う他の方法があるかどうかはわかりませんが、私はこの問題に3日間立ち往生しており、フォーラム、fabricjs doc、およびgoogleに多くの時間を費やしており、実用的な解決策が見つかりません。私を助けることができる何か他のもの。
編集:以下に2つの実用的な解決策があります。cssでそれを行う方法を確認するために私の答えを確認してください。
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
canvas.width = 800;
canvas.height = 600;
css:
/* media query 1 */
#canvas{
width: 400px;
height: 250px;
}
/* media query 2 */
#canvas{
width: 200px;
height: 120px;
}
長所:
すべての解像度は、キャンバスの幅と高さ(800/600)で示されます。
短所:
正方形のキャンバスのアスペクト比(1:1)、cssの高さに基づいて計算する必要がある奇妙なアスペクト比の出力に関する問題にうまく適合します。
original height / original width * new width = new height;
これはCSSの私のリーグから外れています...
少し前にfabric.jsgitの問題のセクションを読んでください。ここでは、処理が遅く、オブジェクトのトランザクションが正しくないため、テクニック(cssサイズ変更)は推奨されていません。これは変更される可能性があります。テストしたところ、オブジェクトのサイズが正しくありません(ランダムな色のピクセル、トランザクションの影はキャンバスに残ります、言い換えれば混乱)
ウィンドウのサイズ変更(レスポンシブキャンバス)でキャンバスのサイズを変更するだけです。正確な寸法にエクスポートする必要がある場合は、キャンバスを正確なピクセル解像度にサイズ変更するか、別のキャンバスを非表示にする必要があります。
この例は、1:1の比率のキャンバス用です(キャンバスと内部のオブジェクトにアスペクト比を適用する必要があります)。
$(window).resize(function (){
if (canvas.width != $(".container").width()) {
var scaleMultiplier = $(".container").width() / canvas.width;
var objects = canvas.getObjects();
for (var i in objects) {
objects[i].scaleX = objects[i].scaleX * scaleMultiplier;
objects[i].scaleY = objects[i].scaleY * scaleMultiplier;
objects[i].left = objects[i].left * scaleMultiplier;
objects[i].top = objects[i].top * scaleMultiplier;
objects[i].setCoords();
}
canvas.setWidth(canvas.getWidth() * scaleMultiplier);
canvas.setHeight(canvas.getHeight() * scaleMultiplier);
canvas.renderAll();
canvas.calcOffset();
}
});
エクスポートキャンバスデータの送信時に、キャンバスのサイズを希望の解像度に変更します。
function GetCanvasAtResoution(newWidth)
{
if (canvas.width != newWidth) {
var scaleMultiplier = newWidth / canvas.width;
var objects = canvas.getObjects();
for (var i in objects) {
objects[i].scaleX = objects[i].scaleX * scaleMultiplier;
objects[i].scaleY = objects[i].scaleY * scaleMultiplier;
objects[i].left = objects[i].left * scaleMultiplier;
objects[i].top = objects[i].top * scaleMultiplier;
objects[i].setCoords();
}
canvas.setWidth(canvas.getWidth() * scaleMultiplier);
canvas.setHeight(canvas.getHeight() * scaleMultiplier);
canvas.renderAll();
canvas.calcOffset();
}
return canvas.toDataURL();
}
);
1:1とは異なる比率では大した問題ではなく、高さのスケールマルチプレイヤーも計算する必要があります。比率はわかりやすいです: http://andrew.hedges.name/experiments/aspect_ratio/
キャンバスをコピーせずにそれを行うためのトリックを見つけました。このソリューションはcssズームプロパティに非常に近いですが、イベントは正しく処理されます。
これは、キャンバスを半分のサイズで表示する例です。
-webkit-transform : scale(0.5);
-webkit-transform-Origin : 0 0;