Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
E' parecchio che consulto questo sito, ed ora ho deciso di iscrivermi per poter avere suggerimenti su problemi
più specifici. Inizio subito con il problema che ho attualmente.
Dovendo organizzare e archiviare le mie fotografie ( + di un migliaio ) e non avendo trovato programmi
già confezionati con le caratteristiche di cui avrei bisogno ( automatismi di catalogazione personalizzata ),
fiducioso della piccola esperienza acquisita con altri progetti in VB, ho deciso di provare con il " faccio da me ".
Il programma dovrebbe popolare un Panel con le miniature delle immagini ( tutte o in parte ) contenute in una
cartella, come " FastStone Image Viewer o XnView ".
Ho utilizzato il metodo OpenFileDialog, ma non riesco a progredire a causa di alcuni problemi.
Ecco il codice a cui sono giunto:
La ricerca e la selezione dei file funzionano, le immagini vengono visualizzate nella posizione corretta ma
una sola per volta, quando viene visualizzata un'immagine scompaiono le precedenti.
Avrei anche bisogno di visualizzare il nome del file relativo e poter selezionare le immagini per effettuare
la catalogazione.
Ringrazio anticipatamente e saluto.
Gianni
Ultima modifica effettuata da Thejuster il 16/02/2020 alle 16:01
Panel1.Controls.Add(pic(Npic))' tutte le pic sono gestite come una matrice
' MsgBox("ok")
Next
EndIf
Devi lavorare sulla gestione dei files nella cartella.
1) devi caricare la lista dei file
2) devi contare quante immagini ci sono
3) devi dimensionare la matrice delle picturebox
Incontrerai anche altri problemi, se carichi molte immagini senza rimensionarle la memoria finirà presto.
Con questo approcio ti sarà difficile mettere i nomi e le caratteristiche delle foto.
Un approcio efficiente è quello di aggiungere un UserControl o ControlloUtente, con il Controllo utente puoi creare l'equivalente di un form dove posizioni una picturebox e una label, più altre cose se ti servono, poi nel tuo form1 che già hai creato con il panel1 aggiungi tutti gli UserControl che vuoi, con la stessa modalità fatta con le picturebox(xx), gli UserControl(xx) hanno lindice per cui nessun problema per identificarli posizionarli e modificarli.
Ultima modifica effettuata da Carlo il 15/02/2020 alle 0:04
Grazie mille Carlo per la tua risposta lampo molto dettagliata, sono ammirato.
Domani leggo attentamente e provo, poi ti faccio sapere.
Buon fine settimana.
P.S.
Chiedo scusa se commetto qualche errore, non sono molto abituato a scrivere.
Mi sono accorto che nel titolo non ho specificato [VB.net], e devo pure imparare ad usare i tag.
Utilizza un FlowLayoutPanel con disposizione Da sinistra verso destra.
I Controlli saranno automaticamente messi uno accanto all'altro e spostati in basso quando serve
con le scrollbar in modo da scorrere.
Come seconda cosa, ti conviene come detto da carlo di ridurre l'immagine.
Una volta aperto in file di disegnare l'immagine di una dimensione tipo 250,250 max
Carichi prima l'immagine in una Bitmap vuota e poi con il graphics la ridisegni 250 x 250 giusto per avere un anteprima.
per risparmiare carico di memoria il controllo picturebox ha una proprietà chiamata Tag da li esempio puoi impostare il percorso originale del file.
Gli esempi di Thejuster sono sempre utili, e come ha affermato è una partenza, ho fatto delle aggiunte:
1) importante liberare la memoria, con img.Dispose()
2) per aggiungere il click ho messo l'istruzione estesa, in VisualStudio2012/2017 p.click, non è riconosciuto, forse ci vuole un Imports ?
3) aggiunto OpenFileDialog con il filtro per le sole immagini
4) variabili H e W per scegliere la dimensione della miniatura
5) l'aspect ratio della miniatura viene calcolato in accordo con l'immagine trattata
6) la finestra di dialogo mostra l'immagine ridimensionabile e alcune info
Codice sorgente - presumibilmente VB.NET
Imports System.IO
PublicClass Form1
PrivateSub ButLOAD_Click(sender AsObject, e As EventArgs)Handles ButLOAD.Click
Dim OpDi As OpenFileDialog =New OpenFileDialog()
OpDi.Multiselect=True
' solo immagini riconosciute
OpDi.Filter="Images(*.jpg *.bmp *.png *.gif *.tif)|*.jpg;*.bmp;*.png;*.gif;*.tif|Tutti i file (*.*)|*.*"
Salve a tutti e grazie delle risposte.
Scusate il ritardo ma ho avuto contrattempi che non ho potuto procrastinare.
Datemi il tempo di leggere le vostre mail poi risponderò.
Scusate ancora.
In questi giorni durante le mie vicissitudini ho potuto lavorare un poco, ma su un pc non collegato in rete,
e non avendo letto le vostre mail ho proseguito seguendo la mia strada.
Ora ho letto, ma ho dovuto constatare che, conoscendo solo genericamente il mio progetto voi avete giustamente
proposto le vostre idee e di questo ringrazio immensamente.
Ma mi sono chiesto se sia giusto farvi perdere del tempo prezioso per cercare di risolvere i miei problemi proponendo
soluzioni che potrebbero anche non essere utili ai miei scopi.
Premettendo che sono sempre curioso di vedere come altri vedono e risolvono lo stesso problema, ho pensato
di preparare un pezzo di codice per darvi modo di vedere ( se lo volete ) come ho impostato la mia Form principale.
Questo codice sarebbe da mettere nella Sub Form Load e dimensiona un Form vuoto:
Codice sorgente - presumibilmente VB.NET
Me.Width=1549'---------------- Larghezza Form 1 ------------------
Me.Height=876'----------------- Altezza Form 1 ------------------
Me.Left=(Screen.PrimaryScreen.Bounds.Width-Me.Width)/2'---------------- Centratura x Form 1 ---
Me.Top=(Screen.PrimaryScreen.Bounds.Height-Me.Height)/ 2 Form 1 ------ Centratura y Form 1 ---
Dim Txtbx AsNew TextBox '------------ Text Box --------------
Detto questo proseguo con i codici, le spiegazioni e i commenti su questo thread.
Cercherò di essere più chiaro possibile, ma ho paura che il post sarà piuttosto lungo e vi prego di farmi sapere
se questa cosa non va bene ed eventualmente come mi devo comportare.
Siccome non ho ancora deciso se utilizzare layout fissi ( probabile ) o ridimensionabili da mouse,
per facilitare i calcoli ho assegnato a delle variabili pubbliche tutti i valori di settaggio.
Codice sorgente - presumibilmente VB.NET
Public Wpanel AsInteger=800'... Larghezza Panel per cambio riga
Public xpicin AsInteger=20'... posizione x inizio righe picturebox
Public xpic AsInteger=20'... posizione x picturebox
Public ypic AsInteger=20'... posizione y picturebox
Public Wpic AsInteger=120'... larghezza picturebox
Public Hpic AsInteger=80'... altezza picturebox
Public ximg AsInteger=5'... posizione x immagine all'interno di picturebox
Public yimg AsInteger=5'... posizione y immagine all'interno di picturebox
Public Wfdim AsString=0.0503'... fattore dimensionamento larghezza immagine all'interno di picturebox
Public Hfdim AsString=0.0445'... fattore dimensionamento altezza immagine all'interno di picturebox
Public hlab AsInteger=15'... altezza label
Public ftxt AsString="Microsoft Sans Serif"'--- Font della label
Public htxt AsInteger=7'... altezza Font della label
Public spWimg AsInteger=20'... spazio orizzontale tra immagini ( e cornici )
Public spHimg AsInteger=30'... spazio verticale tra immagini ( e cornici )
Qui Inizia il codice di attuazione:
Codice sorgente - presumibilmente VB.NET
'Dim Path As String = "G:\Ilmiofotoalbum" '------------------------------ percorso cartelle immagini
Dim ofd1 As OpenFileDialog =New OpenFileDialog()
ofd1.InitialDirectory= Path
ofd1.Multiselect=True
ofd1.Filter="All files|*.*"
ofd1.FilterIndex= 2
ofd1.RestoreDirectory=True
If ofd1.ShowDialog()= DialogResult.OKThen
IfNot Panel1.Controls.Count= 0 Then'------------------- controllo se nel panel ci sono già miniature
Dim iRisp AsInteger
iRisp =MsgBox(" Nel Pannello sono già presenti altre immagini,"& vbCrLf & vbCrLf & _
" [ SI ] Aggiunge le nuove immagini"& vbCrLf & vbCrLf & _
" [ NO ] Cancella le immagini presenti.", 3 + 32)
SelectCase iRisp
Case vbYes
Case vbNo
Panel1.Controls.Clear()
Call sb320()'----------------------------- Routine per cancellare il contenuto del Panel
CaseElse
ExitSub
EndSelect
EndIf
Siccome non ho capito esattamente a cosa serve sapere il numero dei file della cartella, ho pensato che
avrebbe potuto essere utile anche il numero delle sole immagini selezionate , per questo ho implementato
tutte e due le funzioni di conteggio da usare secondo l'esigenza.
Dim din AsNew IO.DirectoryInfo(Path)'---------------------------------------- conteggio file e item
Dim nimg AsInteger=CInt(din.GetFiles.GetLength(0))'------------------ numero file in folder
Dim nitm AsInteger=UBound(files)'-------------------------------------------- numero item in array
Label5.Text=(nitm +1&" - immagini")
Dim Npbx As UInt16 =0'... indice per identificare le pic
'Dim Nlab As UInt16 = 0 '... indice per identificare le label
Dim pic(nimg)As PictureBox '----------------------------------- numero file in folder / numero item in array
Qui ho pensato di realizzare delle miniature con una cornice che cambia colore quando vengono selezionate.
Per fare ciò ho ridimensionato l'immagine da inserire nella PictureBox:
If xpic >= Wpanel Then'----------- larghezza pannello = 880 alla sesta PictureBox passa alla riga successiva
xpic = xpicin
ypic += Hpic + spHimg
EndIf
Panel1.Controls.Add(pic(Npbx))
Panel1.Controls.Add(labtit)
gr_dest.Dispose()
Next
EndIf
MsgBox(Panel1.Controls.Count)
Devo anche ammettere che purtroppo la mia esperienza in VB e la stanchezza di quei quattro neuroni rimasti
( 72 anni ), mi prendono un mucchio di tempo in più di quello che impieghereste voi.
Ma tengo duro perché è la mia passione, viva i bit.
Ho cercato di provare l'esempio di Thejuster perché sarei curioso di vedere il risultato utilizzando FlowLayoutPanel,
ma non sono riuscito a farlo funzionare perché mi da errore sulla riga p.Click += P_Click
'Public Event Click(sender As Object, e As System.EventArgs)' is an event, and cannot be called directly.
Use a 'RaiseEvent' statement to raise an event.
Per quanto riguarda la memoria avrete visto che ho utilizzato il metodo Graphic per ridimensionare le immagini,
( 120 x 8 per la PictureBox e 115 x 76 per l'immagine   anche se ammetto che non pensavo alla memoria ma alla cornice.
Il messaggio di memoria insufficiente è comparso dopo caricato un centinaio di immagini 750 Kb media x 100 = 75 Mb,
ma non so ancora come interpretarlo.
Ho inserito gr_dest.Dispose(), sostituto di img.Dispose(), ma non ho notato differenze.
Altro errore che non ho ancora individuato è che alla fine, quando vado a contare le immagini del pannello,
risultano sempre essere il doppio di quelle effettivamente presenti.
Sto ancora guardando cose del codice di Carlo, ma credo sia ora di chiudere perché le cosa sono andate
per le lunghe.
Torno a ringraziarvi della pazienza, aspetto commenti e Saluto.
Sono riuscito a provare il codice di Carlo, ed ho potuto constatare i vantaggi del metodo FlowLayoutPanel.
Veloce a caricare e non da problemi di memoria, ho caricato più di 800 immagini poi mi sono fermato.
Non ho però capito a cosa serve e come funziona la parte del codice "AddHandler p.Click, AddressOf P_Click",
come non ho capito come gestisce la parte dell'etichetta.
Dovrò poi anche implementare i codici per la selezione delle miniature, ma di questo ne riparliamo
la prossima volta.
Ora proverò a modificare il mio codice con il metodo che mi avete suggerito, poi faccio sapere.
Purtroppo sono abituato a scrivere in C Like e i convertitori online alcune cose non le traducono.
AddHandler al p_Click aggiunge un evento ad un controllo. appunto al momento del click.
Ma, se crei un ciclo per esempio 100 controlli e li reindirizzi tutti allo stesso void del click
allora tutti e 100 controlli risponderanno a quel click.
ed entra in gioco il CType per identificare Quale controllo sta chiamando quel metodo.
e da lì risalire al tag e mostrare l'immagine.
Alla fine cmq lavorandoci un pò puoi ottenere qualcosa genere.
fatto in 5 minuti.