Image Button Base
Create button from image
- Download ButtonImages [Contains button image state sample] - 209.85 KB
- Download ImageButton - 594.1 KB
- Download ImageButton source - 48.49 KB
- Download ImageButton demo - 545.1 KB
Introduction


ImageButton Demo
ImageButtonBase
is custom button that uses image as design.
Background
To use an image as a button design, we cannot use the regular drawing method, the problem if we use the regular drawing method is, image will be blurred when the control size is larger than the normal size.
Left: Normal image before resized, Right: Image after resize to larger size.
To draw the image in order not to be blurred, the solution is to slice the image into 9 parts, and then draw the parts on the control.
9 segments button image.
Original Image |
![]() |
|||||||||
Sliced Image |
|
Sliced image placement description.
Description | Image |
Top Left | ![]() |
Top Center | ![]() |
Top Right | ![]() |
Middle Left | ![]() |
Middle Center | ![]() |
Middle Right | ![]() |
Bottom Left | ![]() |
Bottom Center | ![]() |
Bottom Right | ![]() |
Slicing the Image
To slice the image into 9 parts, we have to crop the image. I use the function below to crop the image:
''' <summary>
''' Crop image
''' </summary>
''' <param name="sImage">Source bitmap</param>
''' <param name="x">X location</param>
''' <param name="y">Y location</param>
''' <param name="w">Width</param>
''' <param name="h">Height</param>
''' <returns>Cropped image</returns>
''' <remarks></remarks>
Private Function CropImage(ByVal sImage As Bitmap, _
ByVal x As Integer, ByVal y As Integer, _
ByVal w As Integer, ByVal h As Integer)
If w <= 0 Or h <= 0 Then
Return New Bitmap(1, 1)
End If
Dim bmp As New Bitmap(w, h)
bmp.SetResolution(96, 96)
Using g As Graphics = Graphics.FromImage(bmp)
g.DrawImageUnscaled(sImage, -x, -y)
End Using
Return bmp
End Function
In this project, I use class TileImages
to generate sliced images:
Public Class TileImages
Implements IDisposable
Public Sub New(ByVal img As Bitmap, ByVal column As Integer, ByVal row As Integer)
Me._SpritImage = img
_SpritImage.SetResolution(96, 96)
Me._Column = column
Me._Row = row
BuildList()
End Sub
Private lst As New List(Of Bitmap)
Private Sub BuildList()
lst.Clear()
If IsNothing(_SpritImage) Then
Return
End If
_ItemWidth = _SpritImage.Width / _Column
_ItemHeight = _SpritImage.Height / _Row
If _ItemWidth * _Column < _SpritImage.Width Then
_ItemWidth += 1
End If
If _ItemHeight * _Row < _SpritImage.Height Then
_ItemHeight += 1
End If
For r As Integer = 0 To _Row - 1
For c As Integer = 0 To _Column - 1
lst.Add(CropImage(_SpritImage, c * _ItemWidth, _
r * _ItemHeight, _ItemWidth, _ItemHeight))
Next
Next
End Sub
''' <summary>
''' Zero base index
''' </summary>
''' <param name="row">Row of image with zero based index</param>
''' <param name="column">Column of image with zero based index</param>
''' <returns>Bitmap</returns>
''' <remarks></remarks>
Public Function GetImage(ByVal row As Integer, _
Optional ByVal column As Integer = 0) As Bitmap
If row < 0 Or column < 0 Then
Return Nothing
End If
Return lst(row * _Column + column)
End Function
Private _SpritImage As Bitmap
Public Property SpritImage() As Bitmap
Get
Return _SpritImage
End Get
Set(ByVal value As Bitmap)
_SpritImage = value
If Not IsNothing(_spritImage)
_SpritImage.SetResolution(96, 96)
End If
BuildList()
Me.OnSpritImageChanged(EventArgs.Empty)
End Set
End Property
Public Event SpritImageChanged _
(ByVal sender As Object, ByVal e As System.EventArgs)
Protected Overridable Sub OnSpritImageChanged(ByVal e As System.EventArgs)
RaiseEvent SpritImageChanged(Me, e)
End Sub
Private _Column As Integer = 1
Public Property Column() As Integer
Get
Return _Column
End Get
Set(ByVal value As Integer)
_Column = value
BuildList()
Me.OnColumnChanged(EventArgs.Empty)
End Set
End Property
Public Event ColumnChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Protected Overridable Sub OnColumnChanged(ByVal e As System.EventArgs)
RaiseEvent ColumnChanged(Me, e)
End Sub
Private _Row As Integer = 1
Public Property Row() As Integer
Get
Return _Row
End Get
Set(ByVal value As Integer)
_Row = value
BuildList()
Me.OnRowChanged(EventArgs.Empty)
End Set
End Property
Public Event RowChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Protected Overridable Sub OnRowChanged(ByVal e As System.EventArgs)
RaiseEvent RowChanged(Me, e)
End Sub
Private _ItemWidth As Integer
Public ReadOnly Property ItemWidth() As Integer
Get
Return _ItemWidth
End Get
End Property
Private _ItemHeight As Integer
Public ReadOnly Property ItemHeight() As Integer
Get
Return _ItemHeight
End Get
End Property
''' <summary>
''' Crop image
''' </summary>
''' <param name="sImage">Source bitmap</param>
''' <param name="x">X location</param>
''' <param name="y">Y location</param>
''' <param name="w">Width</param>
''' <param name="h">Height</param>
''' <returns>Cropped image</returns>
''' <remarks></remarks>
Private Function CropImage(ByVal sImage As Bitmap, _
ByVal x As Integer, ByVal y As Integer, _
ByVal w As Integer, ByVal h As Integer)
If w <= 0 Or h <= 0 Then
Return New Bitmap(1, 1)
End If
Dim bmp As New Bitmap(w, h)
bmp.SetResolution(96, 96)
Using g As Graphics = Graphics.FromImage(bmp)
g.DrawImageUnscaled(sImage, -x, -y)
End Using
Return bmp
End Function
#Region " IDisposable Support "
Private disposedValue As Boolean = False ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: free unmanaged resources when explicitly called
End If
lst.Clear()
' TODO: free shared unmanaged resources
End If
Me.disposedValue = True
End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code.
' Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
Drawing the Images
This control has 4 button states, and each state has an image:
The states:
State | Image |
Normal | ![]() |
Hover | ![]() |
Pressed | ![]() |
Active | ![]() |
To draw the image on control, firstly I draw a sliced image on a bitmap after control resize in method OnSizeChanged
that calls method GenenerateStrechedImage
(you can find this method in class RipsWareImageButtonBase
), then I use that bitmap to draw on the control.
Using the Code
Usage of RipsWareButtonBase
RipsWareImageButtonBase
is inheritance of RipsWareButtonBase
class, I create class RipsWareButtonBase for multipurpose button, so you can use this class to create your own button with your own drawing method.
The use of RipsWareButtonBase
:
Public Class TestButton
Inherits RipsWareButtonBase
Protected Overrides Sub DrawNormalState(ByRef g As System.Drawing.Graphics)
MyBase.DrawNormalState(g)
'Draw the normal image state here
End Sub
Protected Overrides Sub DrawHoverState(ByRef g As System.Drawing.Graphics)
MyBase.DrawHoverState(g)
'Draw the hover image state here
End Sub
Protected Overrides Sub DrawPressedState(ByRef g As System.Drawing.Graphics)
MyBase.DrawPressedState(g)
'Draw the pressed state here
End Sub
Protected Overrides Sub DrawActiveState(ByRef g As System.Drawing.Graphics)
MyBase.DrawActiveState(g)
'Draw the active or focused state here
End Sub
Protected Overrides Sub DrawDisabledState(ByRef g As System.Drawing.Graphics)
MyBase.DrawDisabledState(g)
'Draw the disable state here
End Sub
End Class
Usage of RipsWareImageButtonBase
To use this control, you just drag the control into the form designer like the image above.
Project Structure
- ImageButton.sln
- RipsWareButtonBase.vb -
RipsWareButtonBase
button base class. - RipsWareImageButtonBase.vb -
RipsWareImageButtonBase
class - ImageButtonDesigner.vb - contains
ImageButtonBaseDesigner
forRipsWareImageButtonBase
designer.
- RipsWareButtonBase.vb -
- ImageButtonDemo.sln
- Form1.vb - Test class
History
- 01/11/2011 First created