Récupération d'une matrice de pixels à partir d'une image sans lire les valeurs des pixels sur l'écran et vice versa (ultra

Soyez le premier à donner votre avis sur cette source.

Snippet vu 19 572 fois - Téléchargée 30 fois

Contenu du snippet

Dans une application de reconnaissance de forme, j'avais besoin d'une méthode pour récupérer les données d'une image sous forme d'une matrice et une autre pour générer une image à partir d'une matrice de couleurs. Je pouvais pas utiliser la fontction Point pour réucupérer les données d'une image et SetPixel pour générer l'image à partir de ma matrice car c'est super lent, et le temps de récupération des données d'une image peut atteindre plus de 6 minutes si l'image est d'une taille de 5000 px * 5000 px (c'est grand mais ça correspond à la taille des images de mon application). Après 4 jours de recherche voci le code que ça a donné : un code très simple pour faire la conversion dans les deux sens et c'est ultra rapide (Que c'est beau l'entraide !)

Source / Exemple :


'Le but de ce code est de pouvoir copier une image vers une matrice et vice versa.
'Pour illustrer ceci, ce code va premièrement copier une picturebox dans une matrice
'puis il va recopier cette même matrice dans une autre picture box et les deux
'transformations sont faites d'une manière directe sans passer pixel par pixel (Ultra rapides)

'Insérer deux images Picturebox dans une forme : Picture1 (Source) et Picture2 (Destination)

'Origine de la source (Largement modifiée)

    'KPD-Team 1999
    'URL: http://www.allapi.net/
    'E-Mail: KPDTeam@Allapi.net

Option Explicit
Option Base 1

Private Type BITMAP
    bmType As Long
    bmWidth As Long
    bmHeight As Long
    bmWidthBytes As Long
    bmPlanes As Integer
    bmBitsPixel As Integer
    bmBits As Long
End Type

Private Type Pixel
    Red As Byte
    Green As Byte
    Blue As Byte
End Type

Private Declare Function GetObject Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
Private Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long

Dim Matrice() As Pixel
Dim NHeight, MWidth As Integer

'***************************************************************

'Procedure qui copie une image PictureBox vers une matrice de pixels
Private Sub MatrixFromImage(Picture As PictureBox, Matrice() As Pixel)
    
    Dim PicBits() As Byte, PicInfo As BITMAP
    Dim Size As Long
    Dim i, j As Integer
    Dim Z As Long
    
    GetObject Picture.Image, Len(PicInfo), PicInfo
    
    Size = PicInfo.bmWidth * PicInfo.bmBitsPixel * PicInfo.bmHeight / 8
    
    ReDim PicBits(Size) As Byte
    ReDim Matrice(PicInfo.bmHeight, PicInfo.bmWidth) As Pixel
        
    GetBitmapBits Picture.Image, Size, PicBits(1)
    
    For i = 1 To PicInfo.bmHeight
        For j = 1 To PicInfo.bmWidth
            Z = (i - 1) * PicInfo.bmWidth * 4 + (j - 1) * 4 + 1
            Matrice(i, j).Blue = PicBits(Z)
            Matrice(i, j).Green = PicBits(Z + 1)
            Matrice(i, j).Red = PicBits(Z + 2)
        Next j
    Next i
    
    NHeight = PicInfo.bmHeight
    MWidth = PicInfo.bmWidth
    
End Sub

'***************************************************************

'Procedure qui copie une matrice de pixels vers une image PictureBox
Private Sub ImageFromMatrix(Picture As PictureBox, Matrice() As Pixel)
    Dim PicBits() As Byte
    Dim i, j As Integer
    Dim Z As Long
    
    ReDim PicBits(UBound(Matrice(), 1) * UBound(Matrice(), 2) * 4)
    
    
    
    For i = 1 To UBound(Matrice(), 1)
        For j = 1 To UBound(Matrice(), 2)
            Z = Z + 1
            
            PicBits(Z) = Matrice(i, j).Blue
            PicBits(Z + 1) = Matrice(i, j).Green
            PicBits(Z + 2) = Matrice(i, j).Red
            PicBits(Z + 3) = 0
            
            Z = Z + 3
        Next j
    Next i
    
    SetBitmapBits Picture.Image, UBound(PicBits), PicBits(1)
    Picture.Refresh
End Sub

'***************************************************************

'Corps du programme

Private Sub Form_Load()
    Dim i, j As Integer
    
    Picture1.Picture = LoadPicture("c:\candle.jpg")
    
    'Copie de l'image1 vers une matrice
    Call MatrixFromImage(Picture1, Matrice())
    
    
    'Exemple d'illustration : Inversion des couleurs de l'image
    'Tout les calculs se font maintenant sur la matrice
    
    For i = 1 To NHeight
        For j = 1 To MWidth
            Matrice(i, j).Blue = 255 - Matrice(i, j).Blue
            Matrice(i, j).Green = 255 - Matrice(i, j).Green
            Matrice(i, j).Red = 255 - Matrice(i, j).Red
        Next j
    Next i
    
    'Copie de la matrice vers l'image2
    Call ImageFromMatrix(Picture2, Matrice())
    
End Sub

Conclusion :


J'attends vos remarques, critiques bref ce que vous en pensez ;)
Bonne programmation à tous

A voir également

Ajouter un commentaire Commentaires
Messages postés
1
Date d'inscription
jeudi 8 février 2018
Statut
Membre
Dernière intervention
8 février 2018

Bonjour,

Lorsque j'execute ce programme j'ai le message suivant au niveau de subroutine suivant:

Private Sub ImageFromMatrix(Picture As PictureBox, Matrice() As Pixel)

le message est: "Type définie par l'utilisateur non défini"

Que dois-je faire?


Merci
Messages postés
1
Date d'inscription
dimanche 25 avril 2010
Statut
Membre
Dernière intervention
15 novembre 2012

bonjour à tous,

est ce que quelqu'un pourrait m'expliquer en détail comment faire pour exécuter ce code,en détail please!
et si quelqu'un de vous aurez une idée sur comment calculer la moyenne pour chaque pixel (RGB/3).
svp aidez moi,je suis débutante et c'est mon premier tp sur les images!!!
ps: je travaille sur java

merci
Messages postés
2
Date d'inscription
vendredi 20 novembre 2009
Statut
Membre
Dernière intervention
28 décembre 2009

Pour réussir à utiliser cette aplication , une fois le copy/paste effectuer , il faut bien évidemment nommé tes picturebox, les repérer , par exmple dans les routines données, les noms sont génériques. Il faut bien regarder ce que tu as comme objet.

Sinon ,en tout cas pour moi , il marche très bien. Merci du coup de main !!

Petit question tout de même , si je veux utiliser la matrice une fois capturé, il me suffit de manipuler les trois états de la matrice. Au moment ou je voudrais la réimprimer , il me suffira d'appeler la routine n°2 . Mais pour moi cela ne marche pas... L'image reste dans la configuration initiale comme si elle n'avais pas enregistrer les changements de couleurs .. (comme dans l'exemple d'inversion de couleur..)

Nico
Messages postés
2
Date d'inscription
lundi 23 avril 2007
Statut
Membre
Dernière intervention
15 juin 2007

Ca à l'air méchant mais je ne comprend pas ce que je dois faire de ce code pour qu'il marche :-)
je l'ai copié dans un editeur de visual basic mais j'ai beaucoup d'erreurs.Il n'existe vraiment aucun logiciel pour faire cette conversion image==> matrice??
Please Help !!
Messages postés
172
Date d'inscription
mercredi 29 janvier 2003
Statut
Membre
Dernière intervention
24 février 2008

ouai , bah j'en sert pour charger l'image et l'enregistrer , je fais les traitements avec une matrice. mais je dois quand meme retransferer la matrice dans un picturebox pour la sauvegarder .
Si je charge une image directement dans dibsection , le resultat n'est pas bon , une erreur de redimensionnement de la matrice (ou quelque chose com ca).
Pour moi , le mieu , serai :
Capture d'ecran : BitBlt DibSection.hdc ....
Creer la matrice a partir de ce dib
travaialler sur la matrice
enregistrer le resultat en bmp ou jpg

Mais bon , y'a des erreures je ne sais pas trop travailler avec ces Dibs , donc j'ai laissé tombé , ca prend 10 secondes en plus , mais tampi.
Je m'y mettrai plus tard a ca.
Merci.
Afficher les 9 commentaires

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.