Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 22
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    105

    [VB.NET] Problema bitmap in un thread

    Salve a tutti, sto cercando di copiare da clipboard un'immagine tramite un thread, ma mi da questo errore:
    codice:
    "NullReferenceException non è stata gestita"
    Riferimento a un oggetto non impostato su un'istanza di oggetto.
    Il pezzo di codice del programma dove mi da l'errore è questo:
    codice:
        Private Sub ElaboraFrame()
            Dim frame As Bitmap
            Dim bmap As Image
                'copiamo l'immagine nella clipboard---
                SendMessage(hWnd, WM_CAP_EDIT_COPY, 0, 0)
                'prendiamo l'immagine dalla clipboard
                bmap = Clipboard.GetImage
                frame = New Bitmap(bmap)  '<--- IL PEZZO DI CODICE DOVE DA L'ECCEZIONE
                For i As Integer = 0 To frame.Height - 1
                    For j As Integer = 0 To frame.Width - 1
                        If (frame.GetPixel(j, i).R > 100 And frame.GetPixel(j, i).G > 100 And frame.GetPixel(j, i).B > 100) Then
                            frame.SetPixel(j, i, Color.Red)
                        End If
                    Next
                Next
                'FinestraElaborazione.PBElaborazione.Image = frame
            thr.Abort()
    
        End Sub
    Come detto prima ElaboraFrame() viene fatto partire da un thread, lo stesso codice se fatto partire senza thread va senza problemi, quindi non so più cosa fare per farlo andare.

    Grazie a tutti

  2. #2
    Utente di HTML.it
    Registrato dal
    Apr 2009
    Messaggi
    970
    Il codice che hai postato, anche se di certo non performante, è corretto. L'eccezione viene generata per il fatto che la variabile bmap non contiene un'immagine, anche se la inizializzi copiando l'immagine dalla clipboad. Evidentemente la clipboard non contiene l'immagine della cam, Hai effettuato la connessione?

    Per vedere effettivamente se il problema è quello, basta che apri una qualsiasi immagine con un programma di fotoritocco, copi l'immagine nella clipboard ed esegui il codice che hai postato, facendo attenzione ovviamente che nessun altro scrivi nella clipboard.
    Sbagliare è umano, perseverare è diabolico.

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    105
    No nella clipboard c'è l'immagine, sia perchè la preview della cam è attiva quando faccio partire il thread (vedo la preview nella form dedicata), sia perchè quando genera l'eccezzione aperendo pait e facendo "incolla" mi incolla l'ultimo fotogramma catturato dalla cam.
    Stavo pensando, ma non è che la clipboard essendo un'unica risorsa non duplicabile e non condivisibile, i programmi che ne richiedono l'accesso lo possono fare solo tramite mutua esclusione? Quindi magari il thread essendo un'istanza del programma (e quindi è possibile che ce ne siano più di uno a richiedere la clipboard contemporaneamente) tale risorsa va gestita in maniera particolare sotto un thread?
    e se è così qualcuno può indicarmi come?
    grazie

  4. #4
    Utente di HTML.it
    Registrato dal
    Apr 2009
    Messaggi
    970
    Originariamente inviato da Adanf
    No nella clipboard c'è l'immagine, sia perchè la preview della cam è attiva quando faccio partire il thread (vedo la preview nella form dedicata), sia perchè quando genera l'eccezzione aperendo pait e facendo "incolla" mi incolla l'ultimo fotogramma catturato dalla cam.
    Ho provato il tuo codice e l'unico modo per sollevare quell'eccezione e che in quella variabile non ci sia un'immagine!

    Stavo pensando, ma non è che la clipboard essendo un'unica risorsa non duplicabile e non condivisibile, i programmi che ne richiedono l'accesso lo possono fare solo tramite mutua esclusione? Quindi magari il thread essendo un'istanza del programma (e quindi è possibile che ce ne siano più di uno a richiedere la clipboard contemporaneamente) tale risorsa va gestita in maniera particolare sotto un thread?
    grazie
    Non penso proprio visto che il codice non può essere eseguito in parallelo, per cui anche più Thread che accedono alla clipboard lo fanno in istanti diversi.

    Inserisci un breckpoint nella riga dove assegni l'immagine alla bitmap e controlla che la variabile bmap non sia nulla, ovvero qui:

    codice:
    frame = New Bitmap(bmap)
    Se vuoi essere sicuro, ma ti ripeto non è necessario a mio avviso, sincronizza i Thread con un SyncLock , in questo modo solo un Thread alla volta puo accedere al blocco bloccato.
    Sbagliare è umano, perseverare è diabolico.

  5. #5
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    105
    Ok grazie pirelli72 del tuo aiuto, ma per puro caso inserendo il comando clipboard.clear() mi è sbucata fuori un'altra eccezione con la soluzione incorporata , cioè bastava settare il thread in questo modo prima di avviarlo:
    codice:
    thr.SetApartmentState(ApartmentState.STA)
    visto che i thread di default sono .MTA

    Solo che ora ho un'altro problema purtroppo e cioè non riesco a visualizzare l'elaborazione nella form di output.
    Io ho provato sia in maniera semplice, cioè così:
    codice:
        Private Sub ElaboraFrame()
            Dim frame As Bitmap
            Dim bmap As Image
            'copiamo l'immagine nella clipboard---
            SendMessage(hWnd, WM_CAP_EDIT_COPY, 0, 0)
            'prendiamo l'immagine dalla clipboard
            bmap = Clipboard.GetImage
            frame = New Bitmap(bmap)
            For i As Integer = 0 To frame.Height - 1
                For j As Integer = 0 To frame.Width - 1
                    If (frame.GetPixel(j, i).R > 100 And frame.GetPixel(j, i).G > 100 And frame.GetPixel(j, i).B > 100) Then
                        frame.SetPixel(j, i, Color.Red)
                    End If
                Next
            Next
            FinestraElaborazione.PBElaborazione.Image = frame '<-- VISUALIZZAZZIONE DELL'OUTPUT
            thr.Abort()
        End Sub
    dove non mi da nessun errore, solo che quando avvio l'elaborazione mi appare la picturebox dell'elaborazione bianca, cioè come se nn avesse preso il frame.

    Ho anche provato con un delegato creandolo nella "FinestraElaborazione" in questo modo:
    codice:
    Public Class FinestraElaborazione
        Delegate Sub FinElabCallback(ByVal frame As Bitmap)
        Private Sub FinestraElaborazione_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Me.Top = FinestraPrincipale.Top + 50
            Me.Left = FinestraPrincipale.Right
            FinestraPrincipale.NoScala()
        End Sub
    
        Public Sub finelabdelegate(ByVal frame As Bitmap)
            If (Me.PBElaborazione.InvokeRequired) Then
                Dim dlg As New FinElabCallback(AddressOf finelabdelegate)
                Me.Invoke(dlg, frame)
            Else
                Me.PBElaborazione.Image = frame
                Me.PBElaborazione.Refresh()
            End If
        End Sub
    End Class
    
    Public Class FinestraPrincipale
    Private Sub ElaboraFrame()
            Dim frame As Bitmap
            Dim bmap As Image
            'copiamo l'immagine nella clipboard---
            SendMessage(hWnd, WM_CAP_EDIT_COPY, 0, 0)
            'prendiamo l'immagine dalla clipboard
            bmap = Clipboard.GetImage
            frame = New Bitmap(bmap)
            For i As Integer = 0 To frame.Height - 1
                For j As Integer = 0 To frame.Width - 1
                    If (frame.GetPixel(j, i).R > 100 And frame.GetPixel(j, i).G > 100 And frame.GetPixel(j, i).B > 100) Then
                        frame.SetPixel(j, i, Color.Red)
                    End If
                Next
            Next
            FinestraElaborazione.finelabdelegate(frame)
            thr.Abort()
        End Sub
    End Class
    Ma da lo stesso problema sempre finestra bianca, e son sicuro che nel frame sta volta c'è l'immagine perchè con un breakpoint ho verificato che l'immagine viene copiata nella variabile frame.
    Quindi qui il problema è più serio perchè non da nessun errore, eppure l'errore c'è.

  6. #6
    Utente di HTML.it
    Registrato dal
    Apr 2009
    Messaggi
    970
    Originariamente inviato da Adanf
    Ok grazie pirelli72 del tuo aiuto, ma per puro caso inserendo il comando clipboard.clear() mi è sbucata fuori un'altra eccezione con la soluzione incorporata , cioè bastava settare i
    Per puro caso ti avevo detto di controllare che la variabile bmap non fosse nulla dal primo post.

    l thread in questo modo prima di avviarlo:
    codice:
    thr.SetApartmentState(ApartmentState.STA)
    visto che i thread di default sono .MTA
    Pensavo l'avessi fatto visto che non hai postato la parte di codice che avviava il/i Thread. E' chiaro che puoi accedere alla clipboard solo dai thread STA.

    dove non mi da nessun errore, solo che quando avvio l'elaborazione mi appare la picturebox dell'elaborazione bianca, cioè come se nn avesse preso il frame.
    A me funziona correttamente e la Picturebox viene aggiornata correttamente anche se vedo che ACCEDI nel primo esempio a un controllo da un Thread separato da quello della UI e poi giustamente nel secondo esempio. Sicuramente manca qualcos'altro, altro codice che non hai postato.
    Controlla che la bitmap contenga l'immagine modificata salvandola sul disco,:

    codice:
        frame.Save("C:\foto.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
    tralasciando così errori nel tuo codice in cui magari accedi alla Picturebox in questione.
    Sbagliare è umano, perseverare è diabolico.

  7. #7
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    105
    Originariamente inviato da Pirelli72
    A me funziona correttamente e la Picturebox viene aggiornata correttamente anche se vedo che ACCEDI nel primo esempio a un controllo da un Thread separato da quello della UI e poi giustamente nel secondo esempio. Sicuramente manca qualcos'altro, altro codice che non hai postato.
    Controlla che la bitmap contenga l'immagine modificata salvandola sul disco,:

    codice:
        frame.Save("C:\foto.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
    tralasciando così errori nel tuo codice in cui magari accedi alla Picturebox in questione.
    Ho provato a salvare il frame e l'immagine modificata viene salvata correttamente , quindi è proprio nel comando dove copia il frame nella picturebox il problema.

    Ma tu hai provato il primo codice postato giusto? o il codice col delegato?

  8. #8
    Utente di HTML.it
    Registrato dal
    Apr 2009
    Messaggi
    970
    Solo il primo, era più breve.
    Sbagliare è umano, perseverare è diabolico.

  9. #9
    Utente di HTML.it
    Registrato dal
    Mar 2009
    Messaggi
    105
    Originariamente inviato da Pirelli72
    Solo il primo, era più breve.
    Mhmm, quindi se a te funziona il primo senza delegato, non dovrebbe essere un problema di cross-thread giusto? (anche se forse il codice è un po bruttino così )

  10. #10
    Utente di HTML.it
    Registrato dal
    Apr 2009
    Messaggi
    970
    Esatto, funziona senza sollevare l'eccezione 'Operazione cross-thread non valida'.

    ...anche se forse il codice è un po bruttino così.
    Infatti.
    Sbagliare è umano, perseverare è diabolico.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.