65.9K
CodeProject 正在变化。 阅读更多。
Home

带有缩放/平移功能的图像框控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.43/5 (16投票s)

2005年11月22日

3分钟阅读

viewsIcon

221228

downloadIcon

11279

如何通过添加缩放和平移(滚动)功能来扩展 ImageBox 的功能。

引言

此控件通过包含滚动条来平移图像,并提供一种缩放图像大小的方法,从而扩展了 ImageBox 的功能。 我在这里的目标是向您展示两件事

  1. 如何创建扩展 System.Windows.Forms 控件的自定义控件。
  2. 如何以简单的方式向图像显示添加缩放/平移功能。

创建控件

使用 Microsoft Visual Studio .NET,创建控件的最简单方法是右键单击项目并选择“添加 -> 添加用户控件”。

通过添加一个 GroupBoxTrackBar 和三个用于最小缩放 (25%)、中心缩放 (100%) 和最大缩放 (300%) 的 Label,创建了 Zoom 控件。 我将 GroupBoxTrackBarAnchor 属性设置为 "Right, Top, Left",以便调整窗口大小会调整这些控件的宽度。 为了使 100% LabelGroupBox 的中心对齐,我将 Anchor 属性设置为“Top”。

通过将 Panel 拖放到控件上并调整其大小以填充控件的剩余部分(在 Zoom 控件下方)并将其 Anchor 属性设置为“Left, Top, Right, Bottom”以使其随控件一起调整大小,创建了带有自动滚动条的 Image 控件。 将 AutoScroll 属性设置为 "true"。 最后,我在面板内放置了一个 ImageBox,其 Location = 0,0SizeMode=StretchImage

为了使缩放和滚动条正常工作,必须将属性设置为 AutoScroll=trueSizeMode=StretchImage

// zoom controls
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.TrackBar scrollZoom;
private System.Windows.Forms.Label lblMax;
private System.Windows.Forms.Label lblMin;
private System.Windows.Forms.Label lblCenter;    
// image controls
private System.Windows.Forms.Panel imagePanel;
private System.Windows.Forms.PictureBox imgBox;

开发代码

此时,它变得非常简单。 通过将 ImageBox 放置在 Panel 中,其中 AutoScroll=true,当 ImageBox 的大小超过 Panel 的大小时,Panel 将自动添加滚动条。 因此,您所要做的就是添加代码来获取或设置图像,并添加一些代码来控制缩放。

通过添加一个 public 属性来设置图像。 在这种情况下,我选择通过设置 Browsable(true) 使该属性在设计时可用。 当加载新图像时,我还重新居中缩放滚动,如果图像为 null,则禁用缩放滚动。 最后,我将 ImageBox 的大小设置为等于 Image 的大小,缩放比例为 100%。

正如 yfoulon 在下面的评论中所提到的,添加 scrollZoom.Focus() 应该允许使用鼠标滚轮来缩放图像。 (我没有鼠标,所以我无法测试这一点。)

[Browsable(true),
Description("Image loaded into the box.")]
public Image Image
{
    get
    {
        return imgBox.Image;
    }
    set
    {
        // Set the image value
        imgBox.Image = value;

        // enable the zoom control if this is not a null image
        scrollZoom.Enabled = (value != null);

        if (scrollZoom.Enabled)
        {
            // reset zoom control
            scrollZoom.Value = this.scrollZoom.Maximum/2;

            // Initially, the zoom factor is 100% so set the
            // ImageBox size equal to the Image size.
            imgBox.Size = value.Size;
        }
        else
        {
            // If null image, then reset the imgBox size
            // to the size of the panel so that there are no
            // scroll bars.
            imgBox.Size = imagePanel.Size;
        }
    }
}

缩放由一个 EventHandler 处理,该处理程序在用户滚动缩放 TrackBar 时调用一个方法。 缩放比例目前是一个硬编码的数组,包含 11 个元素,这与 TrackBar 上的位置数量相同(最小 = 0,中心 = 5,最大 = 10)。 然后,通过将 Image 的大小乘以新的缩放比例来调整 ImageBox 的大小。 因为 ImageBoxSizeMode 设置为 "StretchImage",所以 Image 将被缩放到适合 ImageBox 的新大小。

private double[] zoomFactor = 
   {.25, .33, .50, .66, .80, 1, 1.25, 1.5, 2.0, 2.5, 3.0}; 

private void scrollZoom_Scroll(object sender, 
                                System.EventArgs e)
{
    setZoom();
}

private void setZoom()
{
    // The scrollZoom changed so reset the zoom factor
    // based on the scrollZoom TrackBar position.
    double newZoom = zoomFactor[scrollZoom.Value];

    // Set the ImageBox width and height to the new zoom
    // factor by multiplying the Image inside the Imagebox
    // by the new zoom factor.
    imgBox.Width = 
             Convert.ToInt32 ( imgBox.Image.Width * newZoom); 
    imgBox.Height = 
             Convert.ToInt32 ( imgBox.Image.Height * newZoom );
}

此外,我还添加了一个 KeyDown 事件处理程序和一些代码,允许用户使用 Ctrl+ 和 Ctrl- 键来增加或减少缩放比例。

private void ImageBoxPanZoom_KeyDown(object sender, KeyEventArgs e)
{
    // Was the key combination that was pressed Ctrl+ or Ctrl-?
    // If so, then change the zoom level (but only if the zoom
    // is enabled)
    if (scrollZoom.Enabled) 
    {
        // Note: The e.KeyData is the combination of all the
        // keys currently pressed down. To find out if this is
        // the Ctrl key *and* the + key, you "or" the Keys 
        // together. This is a bitwise "or" rather than the 
        // || symbol used for boolean logic.

        if((e.KeyData == (Keys.Oemplus | Keys.Control)) &&
            (scrollZoom.Value != scrollZoom.Maximum))
        {
            scrollZoom.Value++;
            setZoom();
        }
        else if ((e.KeyData == (Keys.OemMinus | Keys.Control)) &&
            (scrollZoom.Value != scrollZoom.Minimum))
        {
            scrollZoom.Value--;
            setZoom();
        }
    }
}

关注点

在某个时候,我想重新审视这个项目,并添加一种使用箭头键和/或鼠标滚动图像的方法。

历史

  • 05/12/01 - 感谢 yfoulon 纠正了我在原始文章中犯的一个错误。 它比我最初想象的还要简单! :)
© . All rights reserved.