Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
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
Codice sorgente - presumibilmente VB.NET
PublicFunction Area(ByVal P As Point, ByVal img As Bitmap, ByVal Coefficente AsInteger)As List(Of Point)
'P punto dove hai cliccato col secchiello
'B è la bitmap In questione
Dim Points AsNew List(Of Point)
Dim NewPoints AsNew List(Of Point)
Dim ColoreAttuale As Color =Nothing
Dim ColoreOggetto As Color = img.GetPixel(P.X, P.Y)
Dim ArrayPoint AsNew List(Of Point)
Points.Add(P)
Do
Try
ForEach 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)
EndIf
ColoreAttuale = img.GetPixel(J.X, J.Y)
If IsNearestColor(ColoreOggetto, ColoreAttuale, Coefficente)=TrueThen'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)
EndIf
EndIf
If d.X < img.Width- 1 Then
d =New Point(K.X+ 1, K.Y)
EndIf
ColoreAttuale = img.GetPixel(d.X, d.Y)
Dim si AsString= ColoreAttuale.ToString
If IsNearestColor(ColoreOggetto, ColoreAttuale, Coefficente)=TrueThen
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)
EndIf
EndIf
If K.Y > 0 Then
s =New Point(K.X, K.Y- 1)
EndIf
ColoreAttuale = img.GetPixel(s.X, s.Y)
If IsNearestColor(ColoreOggetto, ColoreAttuale, Coefficente)=TrueThen
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)
EndIf
EndIf
If Sot.Y < img.Height- 2 Then
Sot =New Point(K.X, K.Y+ 1)
Else
EndIf
If Sot.Y < img.HeightThen
ColoreAttuale = img.GetPixel(Sot.X, Sot.Y)
If IsNearestColor(ColoreOggetto, ColoreAttuale, Coefficente)=TrueThen
If PuntiInseriti.IndexOf(Sot)=-1 Then
immagineRed.SetPixel(Sot.X, Sot.Y, Color.Red)' immagine appartenente alla classe che da errore
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...
Totem ti ringrazio
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 ?
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?
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:
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
Ok ma è possibile che sia il delegato che fà confusione?
In pratica modificavo l'immagine poi la asegnavo al controllo tramite delegato Ho provato a non aggiornare il controllo e l'errore non me lo da più
Come posso fare a vedere i progressi che il programma sta facendo?
se metto un thread.sleep posso risolvere il problema?