私は地図を表示するプログラムを書いており、その上にカメラの位置とその視線方向が表示される別のレイヤーがあります。マップ自体は、ズームおよびパンできます。問題は、マップ ファイルのサイズが大きく、ズームがスムーズに行われないことです。
class ZoomablePictureBox : PictureBox
ズームとパン機能を追加するために作成しました。ズームとパンのために、このフォーラムや他のフォーラムからさまざまな方法を試したところ、次のOnPaint
イベントで発火しましたZoomablePictureBox
。
private void DrawImgZoomed(PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
if (imgZoomed != null)
e.Graphics.DrawImage(imgZoomed, new Rectangle(-ShiftX, -ShiftY, imgZoomed.Width, imgZoomed.Height), 0, 0, imgZoomed.Width, imgZoomed.Height, GraphicsUnit.Pixel);
}
ShiftX と ShiftY は適切なマップ パンを提供します (この問題には計算は関係ありません)。
imgZoomed
ズームが変更されるたびに BackgroundWorker で計算された元のマップのズーム バージョンです。
private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
Bitmap workerImage = e.Argument as Bitmap;
Bitmap result;
result = new Bitmap(workerImage, new Size((int)(workerImage.Width * Zoom), (int)(workerImage.Height * Zoom)));
e.Result = result;
}
したがって、現在のアプローチは、ユーザーがマウスホイールをスクロールするたびに、imgZoomed
現在のズームに基づいて新しいものが計算されるというものです。マップ サイズが 30 MB 以下の場合、最大で 0.5 秒かかるので面倒ですが、パンはスムーズに実行されます。
これが最善の考えではないかもしれないことは承知しています。以前のアプローチでは、マウスがスクロールされるたびにズームされた画像のコピーを作成しませんでしたが、代わりにこれを行いました:
e.Graphics.DrawImage(Image, new Rectangle(-ShiftX, -ShiftY, (int)(this._image.Width * Zoom), (int)(this._image.Height * Zoom)), 0, 0, Image.Width, Image.Height, GraphicsUnit.Pixel);
私が理解していることから、ズームは元の画像を引き伸ばしただけなので、はるかにスムーズでした。一方、パンは激しくスキップしていました。
私は考えていました:
- ズームごとに元のマップのコピーをメモリ/ハード ドライブに作成する - メモリ/HDD スペースを大量に消費します。
- 次/実際/前のズーム用に元のマップのコピーを作成するので、次のステップを計算する時間が増えます - ユーザーが一度に複数のステップをスクロールすると役に立ちません
マトリックス変換も試しましたが、実際のパフォーマンスの向上はなく、パンの計算は本当に骨の折れる作業でした。
私はここでぐるぐる回っていますが、その方法がわかりません。デフォルトの Windows 画像ビューアーでマップを開くと、ズームとパンがスムーズになります。彼らはどのようにそれをしますか?
ズームとパンを同時にスムーズに行うにはどうすればよいですか?