我正在窗口上绘制位图,并且需要模拟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。但是,它并非在所有情况下都有效。

最佳答案

鲍勃·鲍威尔(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;
  }
}

关于c# - 在C#中模拟ImageLayout.Zoom,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7260755/

10-13 05:05