ImageButton that will AutoSize the image

冷暖自知 提交于 2020-01-23 03:36:13

问题


I'm searching for a button control that will AutoSize its image. Normal button controls won't do this. I'm using C#.Net 2.0.

For example, I have a Button that is 200 x 50px and an image that is 800 x 100px. I want to resize the Image so that it is a little to the left, near the text of the button. With a PictureBox I can do this. But when I lay a PictureBox over the Button its very ugly because you can't click there.


回答1:


You can do this as follows:

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

E.g: Or, You can create a new Button type that will change the size of the image:

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

Test:

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);



回答2:


I was looking for a version of this in vb.net, so I started with mykhaylo's answer and improved it a bit. This code resizes the image to fit proportionally, centers the image in the button, and provides inner padding for the image.

This button actually does not use the "Image" property of the button and exposes a property "AutoScaleImage" that should be set alternately.

Here is the C# version - VB.net at bottom. Enjoy!

[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);

  }

}

Or my original VB.NET Version.

<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



回答3:


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

}



回答4:


I originally proposed using a standard ImageButton but then read your comment that you are trying to size the button to the image. For that use a LinkButton:

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


来源:https://stackoverflow.com/questions/2397651/imagebutton-that-will-autosize-the-image

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!