Эмуляция ImageLayout.Zoom in C # - PullRequest
2 голосов
/ 31 августа 2011

Я рисую растровое изображение в окне, и мне нужно эмулировать функциональность 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 голосов
/ 31 августа 2011

Боб Пауэлл написал статью об этом: Масштаб и панорамирование изображения.

В случае, если ссылка умирает, вот опубликованный код из этой статьи:

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;
  }
}
...