将自动调整图像的ImageButton

时间:2010-03-07 19:42:32

标签: c# .net button

我正在搜索将AutoSize其图像的按钮控件。普通按钮控件不会这样做。我正在使用C#.Net 2.0。

例如,我有一个200 x 50px的Button和一个800 x 100px的图像。我想调整图像的大小,使其在按钮文本附近向左一点。使用PictureBox我可以做到这一点。但是当我在PictureBox上放置Button非常难看,因为你无法点击那里。

4 个答案:

答案 0 :(得分:5)

您可以按照以下方式执行此操作:

button.Image = Image.FromFile(path);
button.AutoSize = true;

例如:或者,您可以创建一个新的Button类型来改变图像的大小:

public class AutoSizeButton : Button
{

    public new Image Image
    {
        get { return base.Image; }
        set 
        {
            Image newImage = new Bitmap(Width, Height);
            using (Graphics g = Graphics.FromImage(newImage))
            {
                g.DrawImage(value, 0, 0, Width, Height);
            }
            base.Image = newImage;
        }
    }
}

测试:

AutoSizeButton button = new AutoSizeButton();
button.Location = new Point(27, 52);
button.Name = "button";
button.Size = new Size(75, 23);
button.Text = "Test";
button.UseVisualStyleBackColor = true;
button.Image = Image.FromFile(path);
Controls.Add(button);

答案 1 :(得分:4)

我在vb.net中寻找这个版本,所以我从mykhaylo的回答开始并稍微改进了一下。此代码调整图像大小以按比例调整,使图像在按钮中居中,并为图像提供内部填充。

此按钮实际上不使用按钮的“图像”属性,并显示应交替设置的属性“AutoScaleImage”。

这是C#版本 - 底部是VB.net。享受!

[System.ComponentModel.DesignerCategory("")]
public class AutoScaleButton : Button
{

  private Image _AutoScaleImage;
  public Image AutoScaleImage {
    get { return _AutoScaleImage; }
    set {
      _AutoScaleImage = value;
      if (value != null)
        this.Invalidate();
    }
  }

  private int _AutoScaleBorder;
  public int AutoScaleBorder {
    get { return _AutoScaleBorder; }
    set {
      _AutoScaleBorder = value;
      this.Invalidate();
    }
  }

  protected override void OnPaint(PaintEventArgs e)
  {
    base.OnPaint(e);
    DrawResizeImage(ref e.Graphics);
  }


  private void DrawResizeImage(Graphics g)
  {
    if (_AutoScaleImage == null)
      return;
    int iB = AutoScaleBorder;
    int iOff = 0;
    Rectangle rectLoc = default(Rectangle);
    Rectangle rectSrc = default(Rectangle);

    Size sizeDst = new Size(Math.Max(0, this.Width - 2 * iB), 
          Math.Max(0, this.Height - 2 * iB));
    Size sizeSrc = new Size(_AutoScaleImage.Width, 
          _AutoScaleImage.Height);
    double ratioDst = sizeDst.Height / sizeDst.Width;
    double ratioSrc = sizeSrc.Height / sizeSrc.Width;

    rectSrc = new Rectangle(0, 0, sizeSrc.Width, sizeSrc.Height);

    if (ratioDst < ratioSrc) {
      iOff = (sizeDst.Width - 
        (sizeDst.Height * sizeSrc.Width / sizeSrc.Height)) / 2;
      rectLoc = new Rectangle(iB + iOff, 
            iB, 
            sizeDst.Height * sizeSrc.Width / sizeSrc.Height, 
            sizeDst.Height);
    } else {
      iOff = (sizeDst.Height - (sizeDst.Width * sizeSrc.Height / sizeSrc.Width)) / 2;
      rectLoc = new Rectangle(iB, 
            iB + iOff, 
            sizeDst.Width, 
            sizeDst.Width * sizeSrc.Height / sizeSrc.Width);
    }

    g.DrawImage(_AutoScaleImage, rectLoc, rectSrc, GraphicsUnit.Pixel);

  }

}

或者我原来的VB.NET版本。

<System.ComponentModel.DesignerCategory("")> _
Public Class AutoScaleButton
  Inherits Button

  Private _AutoScaleImage As Image
  Public Property AutoScaleImage() As Image
    Get
      Return _AutoScaleImage
    End Get
    Set(value As Image)
      _AutoScaleImage = value
      If value IsNot Nothing Then Me.Invalidate()
    End Set
  End Property

  Private _AutoScaleBorder As Integer
  Public Property AutoScaleBorder() As Integer
    Get
      Return _AutoScaleBorder
    End Get
    Set(ByVal value As Integer)
      _AutoScaleBorder = value
      Me.Invalidate()
    End Set
  End Property

  Protected Overrides Sub OnPaint(e As PaintEventArgs)
    MyBase.OnPaint(e)
    DrawResizeImage(e.Graphics)
  End Sub

  Private Sub DrawResizeImage(ByRef g As Graphics)

    If _AutoScaleImage Is Nothing Then Exit Sub
    Dim iB As Integer = AutoScaleBorder, iOff As Integer = 0
    Dim rectLoc As Rectangle, rectSrc As Rectangle

    Dim sizeDst As Size = New Size(Math.Max(0, Me.Width - 2 * iB), Math.Max(0, Me.Height - 2 * iB))
    Dim sizeSrc As Size = New Size(_AutoScaleImage.Width, _AutoScaleImage.Height)
    Dim ratioDst As Double = sizeDst.Height / sizeDst.Width
    Dim ratioSrc As Double = sizeSrc.Height / sizeSrc.Width

    rectSrc = New Rectangle(0, 0, sizeSrc.Width, sizeSrc.Height)

    If ratioDst < ratioSrc Then
      iOff = (sizeDst.Width - (sizeDst.Height * sizeSrc.Width / sizeSrc.Height)) / 2
      rectLoc = New Rectangle(iB + iOff, iB, _
                              sizeDst.Height * sizeSrc.Width / sizeSrc.Height, _
                              sizeDst.Height)
    Else
      iOff = (sizeDst.Height - (sizeDst.Width * sizeSrc.Height / sizeSrc.Width)) / 2
      rectLoc = New Rectangle(iB, iB + iOff, _
                              sizeDst.Width, _
                              sizeDst.Width * sizeSrc.Height / sizeSrc.Width)
    End If

    g.DrawImage(_AutoScaleImage, rectLoc, rectSrc, GraphicsUnit.Pixel)

  End Sub

End Class

答案 2 :(得分:2)

public class ExtButton : Button
{

    public new Image Image 
    {
        get { return base.Image; }
        set {
            base.Image = ScaleImage(value, this.Width, this.Height);
        }
    }

    private Image ScaleImage(Image image, int maxWidth, int maxHeight)
    {
        var ratioX = (double)maxWidth / image.Width;
        var ratioY = (double)maxHeight / image.Height;
        var ratio = Math.Min(ratioX, ratioY);

        var newWidth = (int)(image.Width * ratio);
        var newHeight = (int)(image.Height * ratio);

        var newImage = new Bitmap(newWidth, newHeight);
        Graphics.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight);
        return newImage;
    }

}

答案 3 :(得分:0)

我最初建议使用标准的ImageButton但是然后阅读你的评论,你试图将按钮的大小调整为图像。为此使用LinkBut​​ton:

<asp:LinkButton ID="foo" runat="server" OnClick="LinkButton1_Click">   
    <asp:Image ID="imagefoo" runat="server" ImageUrl="~/Foo.jpg" />
</asp:LinkButton>