Visualizzazione dei risultati da 1 a 4 su 4
  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    7

    [VB.NET] Drawstring su immagine con più stringhe

    Salve a tutti. In un progettino, ho la necessità d'inserire più di una stringa in un immagine. Le stringhe da inserire compaiono al click del mouse sulla picturebox
    Uso il metodo drawstring, così strutturato in modo semplice:
    codice:
    ' (variabili globali)
        Dim oldimage As String
        Dim newimagew As String
        Dim textx As String
        Dim format As ImageFormat
        Dim fontx As Font
        Dim color As Color
        Dim position As Point
    
    
    ' evento: picturebox1_click
    Try
                textx = Form1.ComboBox1.SelectedItem
                fontx = New Font(Font.Bold, "22")
                format = Imaging.ImageFormat.Jpeg
                color = Drawing.Color.Red
                image = System.Drawing.Image.FromFile(oldimage)
                tmpsize.Height = image.Height
                tmpsize.Width = image.Width
                PictureBox1.Image = Bitmap.FromFile(oldimage)
    Catch ex As Exception
                MsgBox(ex.Message)
            End Try
    
    ' evento:ListBox2_SelectedIndexChanged
    
                Dim newbitmap As New System.Drawing.Bitmap(image, tmpsize)
                Dim graphics As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(newbitmap)
                graphics.DrawString(textx, fontx, Brushes.Red, e.Location)
                newbitmap.Save(newimagew, format)
                graphics.Dispose()
                newbitmap.Dispose()
                PictureBox1.Image = Bitmap.FromFile(newimagew)
                ComboBox1.SelectedItem = ComboBox1.SelectedItem + 1
    Il codice per una sola immagine alla volta funziona benissimo, inserisce e salva la stringa proprio dove ho cliccato con il mouse, ma:
    - Se voglio inserire una seconda stringa nella stessa immagine: Non funziona
    Mi dà come errore: "Errore Generico GDI+"
    Non so se sia rilevante come informazione, ma vi aggiungo che oldimage e newimagew hanno percorsi differenti. Prende l'immagine da una parte(oldimage) e crea la nuova modificata da un'altra parte(newimagew)
    Qualche suggerimento da darmi? Grazie

  2. #2
    Utente di HTML.it
    Registrato dal
    Mar 2014
    residenza
    Vicenza
    Messaggi
    318
    Il tuo codice non è che sia proprio leggibile (ad esempio e.Location non si sa da dove lo prendi), comunque secondo me il problema è su Image.FromFile, che ha un piccolo bug: una volta letto il file lo tiene bloccato finchè l'applicazione non viene chiusa, e quindi non puoi eseguire altre operazioni.
    Prova a sostituire FromFile con FromStream, io faccio così:

    codice:
    Dim fs As IO.FileStream
    fs = New IO.FileStream(NomeDelFile, IO.FileMode.Open, IO.FileAccess.Read)
    PictureBox1.Image = Image.FromStream(fs)
    fs.Close()
    Sergio

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    7
    Scusami, d'altronde ho anche sbagliato a scrivere il codice agli eventi giusti
    codice:
     Private Sub PictureBox1_Click(sender As System.Object, e As MouseEventArgs) Handles PictureBox1.Click
      Try
                Dim newbitmap As New System.Drawing.Bitmap(image, tmpsize)
                Dim graphics As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(newbitmap)
                graphics.DrawString(textx, fontx, Brushes.Red, e.Location)
                newbitmap.Save(newimagew, format)
                graphics.Dispose()
                newbitmap.Dispose()
                PictureBox2.Image = Bitmap.FromFile(newimagew)
                ComboBox1.SelectedItem += 1
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
        End Sub
    
    
     Private Sub ListBox2_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles ListBox2.SelectedIndexChanged
     textx = ComboBox1.SelectedItem
            fontx = New Font(Font.Bold, "22")
            format = Imaging.ImageFormat.Jpeg
            color = Drawing.Color.Red
            image = System.Drawing.Image.FromFile(oldimage)
            tmpsize.Height = image.Height
            tmpsize.Width = image.Width
            PictureBox1.Image = Bitmap.FromFile(oldimage)
        End Sub
    ma mi sono appena reso conto di star facendo una cosa completamente inutile (ed esserseneresi reso conto solo dopo 1 settimana a sbatterci la testa, è una dura e triste cosa). Perchè con
    codice:
    newbitmap.save(newimagew,format)
    mettendo caso che io riesco a farlo andare per 2 o più stringhe senza che mi compaiano errori, lui memorizzerà sempre una newimagew con l'ultima stringa inserita sovrascrivendo la precedente immagine
    Quindi devo cambiare completamente strada

    Ti ringrazio per il suggerimento, lo sfrutterò

  4. #4
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    7
    Ho trovato la soluzione, la posto così qualcuno può prendere spunto:
    codice:
    (variabili globali)
    Dim oldimage As String
        Dim newimagew As String
        Dim textx As String
        Dim format As ImageFormat
        Dim fontx As Font
        Dim color As Color
        Dim position As Point
    
        Dim tmpsize As System.Drawing.Size
        Dim img As Image
    
    
        Dim np As Integer = 0
        Dim n As Integer = 0
        Dim f_scan As New scan
    
    
        Dim fs As IO.FileStream
    
        Dim newbitmap As System.Drawing.Bitmap
        Dim graphics As System.Drawing.Graphics
    
        Dim text_array(50) As String
        Dim clickx(50) As Point
        Dim count As Integer = 0
        Dim iniziale_img As Boolean = False
    
    Private Sub ListBox2_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) 
    Handles ListBox2.SelectedIndexChanged
    
    (con queste 2 righe di codice faccio apparire le sbarre laterali 
    se l'immagine supera la grandezza del panel, a condizione che
     la picturebox stia all'interno del panel)
            Panel1.AutoScroll = True
            PictureBox1.SizeMode = PictureBoxSizeMode.AutoSize
    
    
            'percorsi delle cartelle di dove il programma si andrà prendere l'immagine originale e dove l'andrà a salvare tramite le listbox
            oldimage = "C:\*******\" & ListBox1.SelectedItem & "\" & ListBox2.SelectedItem
            newimagew = "C:\********\CHN\" & ListBox1.SelectedItem & "\" & ListBox2.SelectedItem
    
    
         
    
            fs = New IO.FileStream(oldimage.ToString, IO.FileMode.Open, IO.FileAccess.Read)
            PictureBox1.Image = Image.FromStream(fs) 'carico l'immagine originale
            fs.Close()
            iniziale_img = True 'con questa variabile dico che sto caricando 
                                              l'immagine originale, senza modifiche
    
        End Sub
    
    Private Sub PictureBox1_Click(sender As System.Object, e As MouseEventArgs) 
    Handles PictureBox1.Click
    
                  'setto le proprietà del testo che deve apparire 
                  '(in questo caso il mio testo si trova in una combobox)
            textx = ComboBox1.SelectedItem
            fontx = New Font(Font.Bold, "22")
            format = Imaging.ImageFormat.Jpeg
            color = Drawing.Color.Red
    
            (count è ancora 0)
            text_array(count) = textx.ToString.Trim 'memorizzo il testo
            clickx(count) = e.Location 'memorizzo coordinate del click del mouse
    
            'Il mio problema, come ha ben detto SirJo , è che la risorsa caricata 
            'poi restava in memoria e non veniva rilasciata
           'Girovagando ho trovato la soluzione adattandola
            Dim obitamp As Bitmap
            If iniziale_img = True Then 'se l'immagine è quella iniziale
                obitamp = New Bitmap(oldimage) 'allora carico l'iniziale
            Else 'altrimenti
                obitamp = New Bitmap(newimagew) 'carico la modificata
            End If
    
            Dim ographics As Graphics
            Dim bmpnew As Bitmap = New Bitmap(obitamp.Width, obitamp.Height)
            ographics = graphics.FromImage(bmpnew)
            ographics.DrawImage(obitamp, New Rectangle
    (0, 0, bmpnew.Width, bmpnew.Height), 0, 0, obitamp.Width, obitamp.Height, GraphicsUnit.Pixel)
            obitamp.Dispose()
            obitamp = bmpnew
    
            Dim obrush As New SolidBrush(Drawing.Color.Red)
            ographics.DrawString(text_array(count), fontx, obrush, clickx(count)) 
    'tramite gli array "text_array" e "clickx" memorizzati in precedenza, 
    il drawstring scrive il testo giusto e lo inserisce proprio dove clicco con il mouse, 
    all'interno della picturebox
            'libero le risorse
            ographics.Dispose()
            fontx.Dispose()
            obrush.Dispose()
            obitamp.Save(newimagew, ImageFormat.Jpeg) 'salvo la nuova immagine modificata
            obitamp.Dispose()
            PictureBox1.ImageLocation = newimagew 'e visualizzo la nuova immagine modificata
    
    
            count += 1 'aumento count che mi serve il prossimo posto dell'array
            ComboBox1.SelectedItem += 1 'aumento l'item della combobox(ne mio caso sono dei numeri, 
    quindi non farà altro che fare tipo 1+1,2+1,ecc)
            iniziale_img = False 'l'immagine non è più quella originale
    
        End Sub

    L'unico problema è la dimensione dell'array che va gestito a seconda delle vostre esigenze.
    Nel mio caso, istanziandolo a 50 mi va più che bene
    Ringrazio Sirjo per avermi fatto notare l'errore

    EDIT
    Ora che ci penso, gli array "text_array" e "clickx" sono inutili, basterebbe modificarli facendoli diventare semplici variabili e fare le assegnazioni senza il count, poichè il programma non fa altro che prendere l'immagine modificata e rimodificarla inserendo un nuovo dato.
    E in effetti,rivedendoli ancora, sono lettaralmente inutili. Basta, inserire "combobox1.selecteditem" al posto di text_array(count) e direttamente "e.location" al posto di clickx.
    Ultima modifica di xarcius; 28-04-2014 a 19:40

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.