まず第一に:私は何をしようとしていますか?
画像を表示するアプリケーションがあります。canvas 要素を使用して画像をレンダリングします。ズームイン、ズームアウト、ドラッグすることができます。この部分は現在完全に機能しています。
しかし、多くのテキストを含む画像があるとしましょう。解像度は 1200x1700 で、キャンバスの解像度は 1200x900 です。最初にズームアウトすると、レンダリング解像度は ~560x800 になります。
私の実際の図面は次のようになります。
drawImage(src, srcOffsetX, srcOffsetY, sourceViewWidth, sourceViewHeight,
destOffsetX, destOffsetY, destWidth, destHeight);
この画像の小さなテキストは、特に他の画像ビューア (IrfanView など) や html の < img > 要素と比較すると、非常に見栄えが悪くなります。
ブラウザの補間アルゴリズムがこの問題の原因であることがわかりました。さまざまなブラウザーを比較すると、Chrome は拡大縮小された画像を最適にレンダリングしますが、それでも十分ではないことがわかりました。
さて、インターウェブの隅々まで 4 ~ 5 時間続けて検索しましたが、必要なものが見つかりませんでした。「imageSmoothingEnabled」オプション、キャンバスでは使用できない「image-rendering」CSS スタイル、フロート位置でのレンダリング、および補間アルゴリズムの多くの JavaScript 実装 (これらは私の目的には遅すぎます) を見つけました。
あなたは、なぜ私がこのすべてをあなたに話しているのかと尋ねるかもしれません: 私がすでに知っている答えを私に与える時間を節約するためです
だから:補間を改善する良い方法はありますか?私の現在のアイデアは、画像オブジェクトを作成し、これをサイズ変更して (img はスケーリング時に適切に補間されるため)、レンダリングすることです。残念ながら、 img.width を適用しても表示される幅にしか影響しないようです...
更新: Simon のおかげで、問題を解決できました。これが私が使用した動的スケーリングアルゴリズムです。アスペクト比を維持することに注意してください。高さパラメータは、より多くのフロート コンピューティングを回避するためだけのものです。現在は縮小のみです。
scale(destWidth, destHeight){
var start = new Date().getTime();
var scalingSteps = 0;
var ctx = this._sourceImageCanvasContext;
var curWidth = this._sourceImageWidth;
var curHeight = this._sourceImageHeight;
var lastWidth = this._sourceImageWidth;
var lastHeight = this._sourceImageHeight;
var end = false;
var scale=0.75;
while(end==false){
scalingSteps +=1;
curWidth *= scale;
curHeight *= scale;
if(curWidth < destWidth){
curWidth = destWidth;
curHeight = destHeight;
end=true;
}
ctx.drawImage(this._sourceImageCanvas, 0, 0, Math.round(lastWidth), Math.round(lastHeight), 0, 0, Math.round(curWidth), Math.round(curHeight));
lastWidth = curWidth;
lastHeight = curHeight;
}
var endTime =new Date().getTime();
console.log("execution time: "+ ( endTime - start) + "ms. scale per frame: "+scale+ " scaling step count: "+scalingSteps);
}