Controle image zoom/dézoom

Soyez le premier à donner votre avis sur cette source.

Snippet vu 9 688 fois - Téléchargée 16 fois

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

Ajouter un commentaire

Commentaires

gillardg
Messages postés
3275
Date d'inscription
jeudi 3 avril 2008
Statut
Membre
Dernière intervention
14 septembre 2014
3 -
exeption non gérée lors de la création du contrôle

si pas d'image =>impossible de faire un resize :-)

Protected Overrides Sub OnClientSizeChanged(ByVal e As System.EventArgs)
MyBase.OnClientSizeChanged(e)
_DestRect = New Rectangle(0, 0, Me.Width, Me.Height)
_rapportX = (_image.Width / Me.Width)
_rapportY = (_image.Height / Me.Height)
End Sub
gillardg
Messages postés
3275
Date d'inscription
jeudi 3 avril 2008
Statut
Membre
Dernière intervention
14 septembre 2014
3 -
je te propose cette correction
ajouter un bitmap image1 (100 X 100) en ressource
il y a évidement moyen de créer ce bitmap en code , à toi de voir
+ le code :)
Public Sub New()
If _image Is Nothing Then
_image = My.Resources.Image1
End If
'pour eviter le scintillement
Me.DoubleBuffered = True
End Sub
lesdis
Messages postés
401
Date d'inscription
mercredi 19 avril 2006
Statut
Membre
Dernière intervention
6 juin 2011
-
J'ai corriger avant ta proposition en excluant les calculs liés a l'image tant que celle ci est inexistante.

Je ne saurais dire si cela est plus interessant que de créer une image par defaut dès le début
Schwerdtle
Messages postés
15
Date d'inscription
jeudi 20 mai 2004
Statut
Membre
Dernière intervention
2 mars 2009
-
Et pourquoi pas un zip maintenant, avec une image ?
Merci et bravo.
gillardg
Messages postés
3275
Date d'inscription
jeudi 3 avril 2008
Statut
Membre
Dernière intervention
14 septembre 2014
3 -
lesdis , je n'en sais pas plus que toi :)

mais le controle PictureBox contient une image initiale

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.