2011-08-01 3 views
2

画像をズームインまたはズームアウトするトラックバーがありますが、スムーズにズームすることはできません。また、200%以上のズームで分割された2番目の遅れもあります。この画像をもっと速くするにはどうすればいいですか?

private void trackBar1_ValueChanged(object sender, EventArgs e) 
{ 
    zoom = trackBar1.Value; 
    zoomValue = (float)(zoom/10.0f); 
    newBitmap = new Bitmap((int)(currWidth * zoomValue), (int)(currHeight * zoomValue)); 

    g = Graphics.FromImage(newBitmap); 
    Matrix mx = new Matrix(); 
    mx.Scale(zoomValue, zoomValue); 

    g.InterpolationMode = InterpolationMode.HighQualityBicubic; 
    g.Transform = mx; 
    g.DrawImage(currImage, new Rectangle(0, 0, currWidth, currHeight)); 
    g.Dispose(); 
    mx.Dispose(); 
    panel1.BackgroundImage = newBitmap; 
} 

私は、ユーザーコントロールの誰かが非常にスムーズにズームするhttp://www.codeproject.com/KB/graphics/YLScsImagePanel.aspxを作りました。遅れは全くありません。私は新しいビットマップにそれが遅れたびに作成していますので、

private void trackBar1_Scroll(object sender, EventArgs e) 
{ 
    imagePanel1.Zoom = trackBar1.Value * 0.02f; 
} 

これは、カスタムコントロールImagePanel.cs

public float Zoom 
{ 
    get { return zoom; } 
    set 
    { 
     if (value < 0.001f) value = 0.001f; 
     zoom = value; 

     displayScrollbar(); 
     setScrollbarValues(); 
     Invalidate(); 
    } 
} 

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 

    //draw image 
    if(image!=null) 
    { 
     Rectangle srcRect,distRect; 
     Point pt=new Point((int)(hScrollBar1.Value/zoom),(int)(vScrollBar1.Value/zoom)); 
     if (canvasSize.Width * zoom < viewRectWidth && canvasSize.Height * zoom < viewRectHeight) 
      srcRect = new Rectangle(0, 0, canvasSize.Width, canvasSize.Height); // view all image 
     else srcRect = new Rectangle(pt, new Size((int)(viewRectWidth/zoom), (int)(viewRectHeight/zoom))); // view a portion of image 

     distRect=new Rectangle((int)(-srcRect.Width/2),-srcRect.Height/2,srcRect.Width,srcRect.Height); // the center of apparent image is on origin 

     Matrix mx=new Matrix(); // create an identity matrix 
     mx.Scale(zoom,zoom); // zoom image 
     mx.Translate(viewRectWidth/2.0f,viewRectHeight/2.0f, MatrixOrder.Append); // move image to view window center 

     Graphics g=e.Graphics; 
     g.InterpolationMode=interMode; 
     g.Transform=mx; 
     g.DrawImage(image,distRect,srcRect, GraphicsUnit.Pixel); 
    } 

} 

からであるが、それか?このようにズームをスムーズにするにはどうすればよいですか?

+0

codeprojectのコードを使用しないのはなぜですか? – Yahia

+2

私はそれを水平にセンタリングしようとすると、イメージの隠された部分が垂直にぶち壊されます。スクロールバーは見た目が小さすぎます。私が現在していることは、それがほんの少しだけズームしないようにしたいのと同じように動作します。 – Jonas

+0

ペイントコードとtrackBar1_ValueChangedコードを分割して、トラックバーに沿ってスクロールするようにします。 – CodingBarfield

答えて

1

@CodingBarfieldで述べたように、trackBar1_ValueChanged()メソッドでスケーリングされたイメージを計算することはお勧めできません。その理由は、ズームが速すぎると、すべての中間ステップ(再表示されないステップであっても)で再スケーリングされたイメージを計算することになります。 OnPaint()方法でスケーリングが100%クリーンなソリューションではありません

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 

    zoom = trackBar1.Value; 
    if (lastZoom != zoom) 
    { 
     // the zoom has changed, clear the cache 
     lastZoom = zoom; 
     imageCache = null; 
    } 

    if (imageCache == null && image != null) 
    { 
     // compute scaled image 
     imageCache = scaleImage(image, zoom); 
    } 

    //draw image 
    if(image!=null) 
    { 
     ... 
    } 
} 

private void trackBar1_ValueChanged(object sender, EventArgs e) 
{ 
    panel1.Invalidate(); 
} 

そして、このような何かを見て OnPaint()方法に自分自身のスケーリングを置く:だから、このように見えるようにする方法を変更しますなぜなら、まだGUIスレッドを少し保持することができるからです。より良いオプションは、バックグラウンドスレッドを使用することですが、これで十分だと思いますし、コーディング時間を節約できます。

また、必要な画像の一部だけを拡大することで、パフォーマンスをさらに向上させることができます。この手法は、ズームの2乗を節約します。したがって、ズームが大きくなるほど、より多くの計算が保存されます。

もう1つの方法は、計算コストの低い補間モードを選択することです。または、低品質の近似を計算して表示し、バックグラウンドスレッドを使用してより良い品質の画像を計算することもできます。

多分、このコードをすべて投げ捨てて、ちょうど少しあなたのニーズに合わせてCodePlex exampleを修正することができます:)。

これが役に立ちます。