在C#中模拟ImageLayout.Zoom

时间:2011-08-31 17:09:22

标签: c# .net image bitmap zoom

我在窗口上绘制位图,我需要模拟ImageLayout.Zoom功能。

这就是我现在正在使用的:

        if (_bitmap.Width > _bitmap.Height)
        {
            ZoomPercent = (int)(((double)ClientRectangle.Width) / ((double)_bitmap.Width) * 100);
        }
        else
        {
            ZoomPercent = (int)(((double)ClientRectangle.Height) / ((double)_bitmap.Height) * 100);
        }

..其中ZoomPercent是一个属性,允许我更改位图的绘制比例。例如,如果ZoomPercent = 200,它将以200%或2.0的比例绘制它,因此1000x1000位图将绘制为2000x2000。

在我看来,上面的代码应该可行,但事实并非如此。例如,如果位图是800x600,那么宽度更大,如果ClientRectangle是1000x1000,那么它应该计算1000/800 = 1.25 * 100 = 125.所以125%。这将位图拉伸为1000x750,适合ClientRectangle。但它并不适用于所有情况。

1 个答案:

答案 0 :(得分:0)

Bob Powell写了一篇关于此的文章:Zoom and pan a picture.

如果链接死亡,这里是该文章发布的代码:

public class ZoomPicBox : ScrollableControl
{

  Image _image;
  [
  Category("Appearance"),
  Description("The image to be displayed")
  ]
  public Image Image
  {
    get{return _image;}
    set
    {
      _image=value;
      UpdateScaleFactor();
      Invalidate();
    }
  }

  float _zoom=1.0f;
  [
  Category("Appearance"),
  Description("The zoom factor. Less than 1 to reduce. More than 1 to magnify.")
  ]
  public float Zoom
  {
    get{return _zoom;}
    set
    {
      if(value < 0 || value < 0.00001)
        value = 0.00001f;
      _zoom = value;
      UpdateScaleFactor();
      Invalidate();
    }
  }

  /// <summary>
  /// Calculates the effective size of the image
  ///after zooming and updates the AutoScrollSize accordingly
  /// </summary>
  private void UpdateScaleFactor()
  {
    if(_image==null)
      this.AutoScrollMinSize=this.Size;
    else
    {
      this.AutoScrollMinSize=new Size(
        (int)(this._image.Width*_zoom+0.5f),
        (int)(this._image.Height*_zoom+0.5f)
        );
    }
  }

  InterpolationMode _interpolationMode=InterpolationMode.High;
  [
  Category("Appearance"),
  Description("The interpolation mode used to smooth the drawing")
  ]
  public InterpolationMode InterpolationMode
  {
    get{return _interpolationMode;}
    set{_interpolationMode=value;}
  }

  protected override void OnPaintBackground(PaintEventArgs pevent)
  {
    // do nothing.
  }

  protected override void OnPaint(PaintEventArgs e)
  {
    //if no image, don't bother
    if(_image==null)
    {
      base.OnPaintBackground(e);
      return;
    }
    //Set up a zoom matrix
    Matrix mx=new Matrix(_zoom, 0, 0, _zoom, 0, 0);
    //now translate the matrix into position for the scrollbars
    mx.Translate(this.AutoScrollPosition.X / _zoom, this.AutoScrollPosition.Y / _zoom);
    //use the transform
    e.Graphics.Transform = mx;
    //and the desired interpolation mode
    e.Graphics.InterpolationMode = _interpolationMode;
    //Draw the image ignoring the images resolution settings.
    e.Graphics.DrawImage(_image, new rectangle(0, 0, this._image.Width, this._image.Height), 0, 0, _image.Width, _image.Height, GraphicsUnit.Pixel);
    base.OnPaint(e);
  }

  public ZoomPicBox()
  {
    //Double buffer the control
    this.SetStyle(ControlStyles.AllPaintingInWmPaint |
                  ControlStyles.UserPaint |
                  ControlStyles.ResizeRedraw |
                  ControlStyles.UserPaint |
                  ControlStyles.DoubleBuffer, true);

    this.AutoScroll=true;
  }
}