【问题标题】:ImageButton that will AutoSize the image将自动调整图像大小的 ImageButton
【发布时间】:2010-03-07 19:42:31
【问题描述】:

我正在寻找一个按钮控件,它将AutoSize 其图像。普通按钮控件不会这样做。我正在使用 C#.Net 2.0。

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

【问题讨论】:

    标签: c# .net button


    【解决方案1】:

    你可以这样做:

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

    【讨论】:

    • taht 将按钮自动调整为图像,而不是图像调整为按钮。为了清楚起见,我将编辑我的问题。
    【解决方案2】:

    我在 vb.net 中寻找这个版本,所以我从 mykhaylo 的答案开始并对其进行了一些改进。此代码调整图像大小以适应比例,将图像置于按钮的中心,并为图像提供内部填充。

    这个按钮实际上并没有使用按钮的“Image”属性,而是暴露了一个应该交替设置的属性“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
    

    【讨论】:

    • 代码无法编译,DrawResizeImage(ref e.Graphics); 抛出错误。但是,在修复它时(ref 中不需要,在 C# 中,除了值类型之外的所有对象都通过引用传递)这正是我想要的。
    【解决方案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】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-28
        • 2017-04-29
        • 1970-01-01
        • 2022-07-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多