Controle image zoom/dézoom

Contenu du snippet

Un petit control permettant de zoomer / dézoomer ainsi que de déplacer l'image, le tout à la souris.

Pas de zip, il suffit juste de copier / coller le code de la classe pour l'intégrer dans une source

Source / Exemple :


Imports System.Drawing.Drawing2D

Public Class ImageBox
    Inherits Control

    Private _image As Image
    Private _zoom As Single = 1
    Private _position As PointF = New PointF(0, 0)
    Private _width, _height, _rapportX, _rapportY As Single
    Private _DestRect, _SrcRect As Rectangle

    Private _LastPoint As Point

    Public Sub New()
        'pour eviter le scintillement
        Me.DoubleBuffered = True
    End Sub

    Public Sub New(ByVal pic As Image)
        'pour eviter le scintillement
        Me.DoubleBuffered = True

        Me.Image = pic
    End Sub

    Public Property Image() As Image
        Get
            Return _image
        End Get
        Set(ByVal value As Image)
            _image = value

            If _image IsNot Nothing AndAlso Me.Width <> 0 AndAlso Me.Height <> 0 Then
                _rapportX = (_image.Width / Me.Width)
                _rapportY = (_image.Height / Me.Height)
            End If

            draw_image(New PointF(0, 0))
        End Set
    End Property

    Private Sub draw_image(ByVal position As PointF, Optional ByVal delta As Single = 0)
        If _image IsNot Nothing Then
            _zoom -= delta / 100

            'Limite du zoom
            If _zoom > 1 Then
                _zoom += delta / 100
            ElseIf _zoom < 0 Then
                _zoom += delta / 100
            Else

                _width = _zoom * _image.Width
                _height = _zoom * _image.Height

                _position.X += (position.X - (position.X * (1 - (delta / 100)))) * _rapportX
                _position.Y += (position.Y - (position.Y * (1 - (delta / 100)))) * _rapportY

                '************ Vérification pour que l'image ne sorte pas du cadre **************
                If _position.X < 0 Then
                    _position.X = 0
                End If
                If _position.Y < 0 Then
                    _position.Y = 0
                End If

                If _position.Y + ((Me.Height * _rapportY)) * _zoom > _image.Height Then
                    _position.Y -= (_position.Y + ((Me.Height * _rapportY)) * _zoom) - _image.Height
                End If
                If _position.X + ((Me.Width * _rapportX)) * _zoom > _image.Width Then
                    _position.X -= (_position.X + ((Me.Width * _rapportX)) * _zoom) - _image.Width
                End If
                '*********************************************************************************

                _SrcRect = New Rectangle(_position.X, _position.Y, _width, _height)
            End If

        End If
        Me.Invalidate()
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)
        If _image IsNot Nothing Then
            e.Graphics.DrawImage(_image, _DestRect, _SrcRect, GraphicsUnit.Pixel)
        Else
            e.Graphics.FillRectangle(Brushes.White, _DestRect)
            e.Graphics.DrawRectangle(Pens.Black, 0, 0, Me.Width - 1, Me.Height - 1)
        End If
    End Sub

    Protected Overrides Sub OnMouseWheel(ByVal e As System.Windows.Forms.MouseEventArgs)
        MyBase.OnMouseWheel(e)
        draw_image(e.Location, e.Delta / 30)
    End Sub

    Protected Overrides Sub OnMouseEnter(ByVal e As System.EventArgs)
        MyBase.OnMouseEnter(e)
        Me.Focus() 'l'évènement mousewheel ne fonctionne que lorsque le controle possède le focus
    End Sub

    Protected Overrides Sub OnMouseLeave(ByVal e As System.EventArgs)
        MyBase.OnMouseLeave(e)
        Me.Parent.Focus() 'on redonne le focus au controleur parent pour stopper les évènement mousewheel
    End Sub

    Protected Overrides Sub OnClientSizeChanged(ByVal e As System.EventArgs)
        MyBase.OnClientSizeChanged(e)
        _DestRect = New Rectangle(0, 0, Me.Width, Me.Height)
        If _image IsNot Nothing Then
            _rapportX = (_image.Width / Me.Width)
            _rapportY = (_image.Height / Me.Height)
        End If
    End Sub

    Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
        MyBase.OnMouseDown(e)
        _LastPoint = e.Location
    End Sub

    Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
        MyBase.OnMouseMove(e)
        If e.Button = Windows.Forms.MouseButtons.Left Then
            _position.X += ((_LastPoint.X - e.X) * _zoom) * _rapportX
            _position.Y += ((_LastPoint.Y - e.Y) * _zoom) * _rapportY

            draw_image(New PointF(0, 0))

            _LastPoint = e.Location
        End If
    End Sub

    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        MyBase.Dispose(disposing)
        If _image IsNot Nothing Then
            _image.Dispose()
        End If
    End Sub
End Class

Conclusion :


Je n'ai pas mis beaucoup de commentaire par flemme, j'en rajouterais si cela vous semble nécessaire.

Et comme d'habitude, si vous avez des propositions d'améliorations, je suis preneur :)

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.