Oppure

Loading
26/01/10 13:49
Federico1976
Salve a Tutti sto cercandi di fare un programmino che mi anilizza un immagine
ho fatto una classe che ha il compito di trovare tutti gli oggetti o aree in un immagine
e uso un thread dichiaro le immagini a livello di classe però mi da errore come da titolo
quando la nodifico posto un po di codice


    Public Function Area(ByVal P As Point, ByVal img As Bitmap, ByVal Coefficente As Integer) As List(Of Point)
        'P punto dove hai cliccato col secchiello
        'B è la bitmap In questione
        Dim Points As New List(Of Point)
        Dim NewPoints As New List(Of Point)
        Dim ColoreAttuale As Color = Nothing
        Dim ColoreOggetto As Color = img.GetPixel(P.X, P.Y)
        Dim ArrayPoint As New List(Of Point)

        Points.Add(P)
        Do

            Try
                For Each K As Point In Points
                    Dim J As Point
                    Dim d As Point
                    Dim s As Point
                    Dim Sot As Point
                    'testa il punto a destra di questo
                    If K.X > 0 Then
                        J = New Point(K.X - 1, K.Y)
                    Else
                        J = New Point(K.X, K.Y)
                    End If

                    ColoreAttuale = img.GetPixel(J.X, J.Y)
                    If IsNearestColor(ColoreOggetto, ColoreAttuale, Coefficente) = True Then 'Funzione Di Confronto Colore con coefficente
                        If PuntiInseriti.IndexOf(J) = -1 Then
                            immagineRed.SetPixel(J.X, J.Y, Color.Red)' immagine appartenente alla classe che da errore
                            NewPoints.Add(J)
                            PuntiInseriti.Add(J)
                            ArrayPoint.Add(J)
                        End If
                    End If
                    If d.X < img.Width - 1 Then
                        d = New Point(K.X + 1, K.Y)
                    End If

                    ColoreAttuale = img.GetPixel(d.X, d.Y)
                    Dim si As String = ColoreAttuale.ToString
                    If IsNearestColor(ColoreOggetto, ColoreAttuale, Coefficente) = True Then
                        If PuntiInseriti.IndexOf(d) = -1 Then
                            immagineRed.SetPixel(d.X, d.Y, Color.Red)' immagine appartenente alla classe che da errore
                            NewPoints.Add(d)
                            PuntiInseriti.Add(d)
                            ArrayPoint.Add(d)
                        End If
                    End If
                    If K.Y > 0 Then
                        s = New Point(K.X, K.Y - 1)
                    End If

                    ColoreAttuale = img.GetPixel(s.X, s.Y)
                    If IsNearestColor(ColoreOggetto, ColoreAttuale, Coefficente) = True Then
                        If PuntiInseriti.IndexOf(s) = -1 Then
                            immagineRed.SetPixel(s.X, s.Y, Color.Red)' immagine appartenente alla classe che da errore
                            NewPoints.Add(s)
                            PuntiInseriti.Add(s)
                            ArrayPoint.Add(s)
                        End If
                    End If

                    If Sot.Y < img.Height - 2 Then
                        Sot = New Point(K.X, K.Y + 1)
                    Else

                    End If
                    If Sot.Y < img.Height Then
                        ColoreAttuale = img.GetPixel(Sot.X, Sot.Y)
                        If IsNearestColor(ColoreOggetto, ColoreAttuale, Coefficente) = True Then

                            If PuntiInseriti.IndexOf(Sot) = -1 Then
                                immagineRed.SetPixel(Sot.X, Sot.Y, Color.Red)' immagine appartenente alla classe che da errore
                                NewPoints.Add(Sot)
                                PuntiInseriti.Add(Sot)
                                ArrayPoint.Add(Sot)

                            End If
                        End If
                    End If
                Next
            Catch ex As Exception
                MsgBox("Area: " & ex.Message & vbCrLf & ex.StackTrace)
            End Try

            Points.Clear()
            Points.AddRange(NewPoints)
            NewPoints.Clear()

        Loop Until Points.Count = 0
        immagineRed = img
        Return ArrayPoint

    End Function

non riesco proprio a capire perche fa quell'errore vi ringrazio tanto dell'aiuto:-?
Ultima modifica effettuata da Il Totem 27/01/10 9:03
aaa
26/01/10 18:21
Federico1976
ho scoperto che sensa thread lerrore non si presenta ma essendo un processo al quanto lungo devo usare per forsa un thread
nessuno mi puo aiutare ?
aaa
27/01/10 9:08
Il Totem
Se l'oggetto immagine è lo stesso per entrambi i thread, puoi fare due cose. Rendere la variabile img Thread-Static (ossia unica per ogni thread), applicandole l'attributo ThreadStatic: in questo caso, però, img deve essere dichiara Shared.
La seconda soluzione consiste nel clonare l'oggetto prima di usarlo, in modo che i due thread utilizzino dati identici ma diversi (nel senso che non si riferiscono allo stesso oggetto). img.Clone() restituisce il clone di img. Se usi questo metodo, devi aggiungere un parametro alla tua funzione che indichi su quale immagine lavorare...
aaa
27/01/10 11:01
Federico1976
Totem ti ringrazio :hail:
il problema che ora ma da un tipo diverso di errore ho provato ad usare clone e Shared ma
con clone mi da questo errore: "bitmap già bloccata."
cosa so sbaliando?
Con Shared devo dichiarare la variabile in un modulo? o nella classe del form ?
aaa
27/01/10 11:30
Federico1976
io ho fatto cosi ho clonato limmagine passando il clone dell'immagine alla funzione è giusto ?
cosa intendi per aggiungere un parametro che indichi su quale immagine lavorare?
aaa
27/01/10 11:32
Federico1976
se passo un clone alla funzione con dei parametri byval non sono due oggetti distinti?
aaa
30/01/10 8:33
Il Totem
Tra parentesi, gli oggetti vengono sempre passati per indirizzo, anche con byval (proprio perchè sono oggetti, gestiti tramite puntatori).
E sì, se crei due oggetti diversi non può darti errore per "oggetto già bloccato", perchè i due SONO a tutti gli effetti due istanze completamente distinte. Hai richiamato la funzione due volte con i parametri diversi? Ad esempio:
funzione(..., img)
funzione(..., img.clone)
aaa
11/02/10 19:18
Federico1976
Inanzitutto Grazie
In pratica si richiamo la funzione (Area) in un ciclo che scorre tutti i pixel dell'immagine quando trova il colore diverso dallo sfondo invio la solita immagine modificata ed ogni volta assegnata al controllo tramite delegato, la funzione area ricerca tutti i pixel apparteneti al solito oggetto cioè attaccati, ho anche provato a lavorare in memoria con (System.Runtime.InteropServices.Marshal.Copy) ma non ho otenuto grandi risultati
la funzione che richiama (Area) è:

Sub Parser()
If immagine Is Nothing Then
Exit Sub
End If
Dim Larghezza As Integer = immagine.Width - 1 'Larghezza
Dim Altezza As Integer = immagine.Height - 1 'Altezza
Dim x As Integer
Dim y As Integer
Dim ColoreAttuale As Color

' GDI+ still lies to us - the return format is BGR, NOT RGB.
Dim bmData As BitmapData = Immagine.LockBits(New Rectangle(0, 0, Immagine.Width, Immagine.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb)

Dim stride As Integer = bmData.Stride
Dim Scan0 As System.IntPtr = bmData.Scan0
Dim bytes As Integer = Immagine.Width * Immagine.Height * 3
Dim p(bytes - 1) As Byte
' Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(Scan0, p, 0, bytes)


'finire da qui e lavorare su p variabile puntatore di area di memoria

If Funzione = Funzioni.TrovaOggettiDiUnColore Then
If _coloreSfondo = Nothing Then
MsgBox("Per La funzione di ricerca degli oggetti Di un Colore bisogna selezionare pripa il colore da catturare";)
Exit Sub
End If
Else 'Se Gli oggetti sono di piu colori iposto il colore di sfondo
' e inposto la variabile boleana a false cosi che ogni colore diverso lo considera un oggettto
'Trova_Escludi = False
If _coloreSfondo = Nothing Then
_coloreSfondo = Color.FromArgb(p(0), p(1), p(2)) '
End If
End If
immagineRed = DirectCast(Immagine.Clone, Bitmap)


Dim c As Integer = 0
Dim nOffset As Integer = stride - bmData.Width * 3


For y = 0 To Altezza
For x = 0 To Larghezza
'Debug.Assert(Control.InvokeRequired = False)
If y = 42 Then
Threading.Thread.Sleep(10)
End If
'ColoreAttuale = Immagine.GetPixel(x, y)
ColoreAttuale = Color.FromArgb(p(c + 2), p(c + 1), p(c))
'Application.DoEvents()

If PuntiInseriti.IndexOf(c) = -1 Then
If IsNearestColor(_coloreSfondo, ColoreAttuale, CoefficenteSfondo) = False Then 'Funzione Di Confronto Colore con coefficente
Application.DoEvents()
Oggetto = New OggettiImmagine
Oggetto.coefficente = CoefficenteOggetto
Oggetto.colore = ColoreAttuale
Oggetto.point = Area(c, immagineRed.Clone, CoefficenteOggetto)
If Oggetto.point.Count > PuntiPerPallino Then
_Oggetti.Add(Oggetto)
End If
If Control IsNot Nothing Then
SetImage(Red_Imagine, Control)
End If

End If
End If
c += 3
Next
c += nOffset
Next

Immagine.UnlockBits(bmData)

End Sub
aaa