Erreur: Mémoire insuffisante avec un GetPixel

Résolu
jimy neutron Messages postés 491 Date d'inscription mercredi 1 février 2006 Statut Membre Dernière intervention 18 novembre 2016 - 5 juin 2012 à 14:30
jimy neutron Messages postés 491 Date d'inscription mercredi 1 février 2006 Statut Membre Dernière intervention 18 novembre 2016 - 6 juin 2012 à 09:04
Bonjour,

Voici mon code:
Imports System.Drawing

Public Class Tab
    Inherits System.Windows.Forms.Form

    'API
    Private Declare Function GetPixel Lib "gdi32" (ByVal hdc As Integer, ByVal X As Integer, ByVal Y As Integer) As Integer
    Private Declare Function GetDC Lib "user32" (ByVal hWnd As IntPtr) As Integer
    Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long

 
    Private Sub Cmd_ReadPixelC_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Cmd_ReadPixelC.Click

        ' Dim ThePen As New System.Drawing.Pen(Color.Black)
        Dim SizeH As Long = Cmp.Height
        Dim SizeL As Long = Cmp.Width

        Dim Index As Long = 0
        Dim IndexCol As Long = 0
        Dim IndexLine As Long = 0
        Dim NivGrayC As Integer = 0
        Dim colorVal As Integer = 0
        Dim PRed As Integer = 0
        Dim PGreen As Integer = 0
        Dim PBlue As Integer = 0
        Dim SomPxC As Long = 0

        Me.LabEncours.Visible = True

        'Scan de l'image
        For IndexCol = 0 To SizeL
            For IndexLine = 0 To SizeH

                colorVal = GetPixel(GetDC(0&), Cmp.Left + IndexCol, Cmp.Top + IndexLine)
                PRed = colorVal And &HFF
                PGreen = (colorVal And &HFF00) / 256
                PBlue = (colorVal And &HFF0000) / 65536
                NivGrayC = (77 * PBlue + 151 * PGreen + 28 * PRed) / 256
                Index = Index + 1
                SomPxC = SomPxC + NivGrayC
            Next
        Next
        Me.LabEncours.Visible = False
        Me.LabC_Gray.Text = (SomPxC / Index).ToString

        Call ReleaseDC(0, GetDC(0&))
    End Sub
End Class



En fait j'ai un Form (Tab) qui propose le show par un bouton d'un autre form (appelé "Cmp" dans le code.)
Et un autre bouton pour scanner tous les pixels de l'écran sous "Cmp".

Le problème, c'est que cela fonctionne bien, mais une seule fois.
Si je relance, même plusieurs minutes plus tard, l'appli plante en "Mémoire insuffisante" ou "La référence d'objet n'est pas définie à une instance d'un objet"

Auriez-vous une idée?

Je précise que je suis en VB 2010 sous framework 3.5 (pas le choix)

Merci d'avance ;)
Jimy

Pensez: Réponse acceptée
'**********************************************

7 réponses

ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
5 juin 2012 à 14:43
Bonjour,
1) Ta déclaration de la fonction ReleaseDC est en type Long ! A corriger !
2) Essaye d'éviter les expressions du genre :
 GetPixel(GetDC(0&)....

Call ReleaseDC(0, GetDC(0&))

extrait ton GetDc(0) u ne seule fois ===>> en toto,
Puis :
GetPixel(toto, ....
Call ReleaseDC(0, toto)

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
3
Utilisateur anonyme
5 juin 2012 à 23:26
Tu peux très bien recopier sur un bitmap une portion d'écran afin d'en analyser l'un de ses pixels.
Voici un petit code commenté pour l'exemple :
'déclaration d'un bitmap 32 millions couleurs de 50 pixels de côté
Dim b As New Bitmap(50, 50, Imaging.PixelFormat.Format32bppArgb)
'outils de dessin sur le bitmap
Dim g As Graphics = Graphics.FromImage(b)
'recopie d'une portion d'écran sur le bitmap depuis les coordonnées screen x 100 et y 100
g.CopyFromScreen(100, 100, 0, 0, New Size(b.Width, b.Height), CopyPixelOperation.SourceCopy)
'analyse du pixel du centre (50/2)
Dim couleur_lue As Color = b.GetPixel(25, 25)
'affichage des composantes RVB de la couleur du pixel
MessageBox.Show(String.Format("rouge={0}, vert={1}, bleu={2}", couleur_lue.R, couleur_lue.G, couleur_lue.B))
3
Utilisateur anonyme
5 juin 2012 à 14:38
Bonsoir,

Pourquoi ne pas avoir utilisé les outils inclus dans le framework (voir Bitmap et sa méthode GetPixel) plutôt que des API ?
0
jimy neutron Messages postés 491 Date d'inscription mercredi 1 février 2006 Statut Membre Dernière intervention 18 novembre 2016 1
5 juin 2012 à 15:08
Merci de vos réponses,

Ucfoutu, je regarde cela de suite. :)

Banana32, je ne travaille pas sur une image que j'ouvre dans un picturebox (jpg ou autres) mais directement sur l'image envoyée par une camera industrielle d'une autre appli.




Je dois comparer la moyenne des niveaux de gris des deux images.
Je scanne donc chaque pixels de l'image de reference, une seule fois.
Puis pour chaque image en cours, je fais de même et compare les moyennes.

Jimy

Pensez: Réponse acceptée
'**********************************************
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
NHenry Messages postés 15113 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 22 avril 2024 159
5 juin 2012 à 19:09
Bonjour,

Comment tu mets à jour ta PictureBox ?

De mémoire, quand j'avais fait cela, je mettais en place un système pour demander explicitement le rafraichissement.

Sinon, je pense qu'il y a un moyen de copier le contenu d'un bitmap.

---------------------------------------------------------------------
[list=ordered][*]Pour poser correctement une question et optimiser vos chances d'obtenir des réponses, pensez à lire le règlement CS, celui-ci pour bien poser votre question ou encore celui-ci pour les PFE et autres exercices.[*]Quand vous postez un code, merci d'utiliser la coloration syntaxique (3ième icône en partant de la droite : ).[*]En VB.NET pensez à activer Option Explicit et Option Strict (propriété du projet) et à retirer l'import automatique de l'espace de nom Microsoft.VisualBasic (onglet Références dans les propriétés du projet).[*]Si votre problème est résolu (et uniquement si c'est le cas), pensez à mettre "Réponse acceptée" sur le ou les messages qui vous ont aidés/list
---
Mon site
0
jimy neutron Messages postés 491 Date d'inscription mercredi 1 février 2006 Statut Membre Dernière intervention 18 novembre 2016 1
5 juin 2012 à 21:17
Salut NHenry

Comme expliqué au dessus, les deux images ci-dessus sont affichées par une application industrielle, je n'ai pas accès aux fichiers pour les charger dans des pictureboxs.
La seule solution est de venir scanner les deux images telles quelles, puis les comparer. J'utilise donc un form, avec une opacité à 20%, placée au dessus et je scanne chaque pixel, je le fais pour l'image de référence, puis pour l'image en cours et je compare.
Mon code fonctionne si je ne l’exécute qu'une fois. A la seconde exécution, l'appli plante.

Jimy

Pensez: Réponse acceptée
'**********************************************
0
jimy neutron Messages postés 491 Date d'inscription mercredi 1 février 2006 Statut Membre Dernière intervention 18 novembre 2016 1
6 juin 2012 à 09:04
Merci Ucfoutu, c'est bien l'appel du GetDC à répétition qui posait problème.

Banana32, ton idée est séduisante, je vais creuser. Merci aussi! ;)


Jimy

Pensez: Réponse acceptée
'**********************************************
0
Rejoignez-nous