Visualizza il feed RSS

MarcoGG : Articoli Blog

[VB.NET] Disegnare su Bitmap

Valuta questo inserimento
di pubblicato il 26-06-2011 alle 17:36 (3785 Visite)
Descrizione :
Tecnica per disegnare su Bitmap di sfondo e salvare il risultato finale nel formato immagine desiderato.

Tratto da :
http://forum.masterdrive.it/visual-b...atabase-56195/

"Disegnare in una PictureBox" è un task piuttosto comune e richiesto in svariate applicazioni.
Di fatto si disegna su una Bitmap in memoria ( che ha le stesse dimensioni in pixels della PBX... ), e chiaramente le coordinate del Mouse sono prese nell'area della PBX.
Con un semplice PBX.Refresh() mi assicuro che l'immagine visualizzata nella PBX sia sempre aggiornata, quindi, all'atto pratico sembra proprio che stia disegnando "nella PBX"...
Tutto quello di cui ho bisogno per l'esempio, è una FormMain, con una PictureBox "PBX" e un paio di Button : "cmd_salva" e "cmd_reset".
Ho aggiunto all'esempio base anche un NumericUpDown "nud_tratto" e una ColorPickerCombo "CPC".
La "ColorPickerCombo" è questa :
http://forum.masterdrive.it/blogs/ma...wn-colors-114/
La disponibilità di una scelta sia sullo spessore del tratto, sia sul colore, permette già una certa varietà.



Due Bmp in memoria, una per l'immagine di sfondo ( caricamento da disco una volta sola ), e una ( copia ) su cui disegnare e salvare.
L'operazione di Reset elimina ogni disegno precedente creando una nuova Bmp Corrente dalla Bmp di Sfondo.

--> Codice FormMain :

codice:
Public Class FormMain

    Private drawOn As Boolean
    Private drawColor As Color
    Private drawWidth As Single
    Private P As New Pen(drawColor, drawWidth)
    Private B As New SolidBrush(drawColor)
    Private prevX As Integer
    Private prevY As Integer
    Private X As Integer
    Private Y As Integer
    Private bmpSfondo As Bitmap
    Private bmpCorrente As Bitmap
    Private percorsoImgs As String = Application.StartupPath & "\"

    Private Function GetBitmap(ByVal nomeFile As String) As Bitmap

        Using FS As New System.IO.FileStream(nomeFile, IO.FileMode.Open, IO.FileAccess.Read)
            Return Bitmap.FromStream(FS)
        End Using

    End Function

    Private Sub FormMain_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        bmpSfondo = GetBitmap(percorsoImgs & "macchina.bmp")
        bmpCorrente = New Bitmap(bmpSfondo)
        PBX.Image = bmpCorrente
        drawWidth = nud_tratto.Value
        drawColor = CPC.PickedColor
        P = New Pen(drawColor, drawWidth)

    End Sub

    Private Sub PBX_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PBX.MouseDown

        If e.Button = Windows.Forms.MouseButtons.Left Then
            drawOn = True
            PBX.Cursor = Cursors.Cross
            X = e.X - drawWidth / 2
            Y = e.Y - drawWidth / 2
            prevX = e.X
            prevY = e.Y
            Using G As Graphics = Graphics.FromImage(bmpCorrente)
                G.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
                G.FillEllipse(B, X, Y, drawWidth, drawWidth)
            End Using
            PBX.Refresh()
        End If

    End Sub

    Private Sub PBX_MouseUp(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PBX.MouseUp

        If e.Button = Windows.Forms.MouseButtons.Left Then
            drawOn = False
            PBX.Cursor = Cursors.Default
        End If

    End Sub

    Private Sub PBX_MouseMove(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles PBX.MouseMove

        If drawOn = False Then Exit Sub
        X = e.X - drawWidth / 2
        Y = e.Y - drawWidth / 2

        Using G As Graphics = Graphics.FromImage(bmpCorrente)

            G.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
            G.DrawLine(P, prevX, prevY, e.X, e.Y)
            G.FillEllipse(B, X, Y, drawWidth, drawWidth)

        End Using

        prevX = e.X
        prevY = e.Y
        PBX.Refresh()

    End Sub

    Private Sub cmd_salva_Click(sender As System.Object, e As System.EventArgs) Handles cmd_salva.Click

        bmpCorrente.Save(percorsoImgs & "output.gif", Imaging.ImageFormat.Gif)

    End Sub

    Private Sub cmd_reset_Click(sender As System.Object, e As System.EventArgs) Handles cmd_reset.Click

        bmpCorrente = New Bitmap(bmpSfondo)
        PBX.Image = bmpCorrente

    End Sub

    Private Sub nud_tratto_ValueChanged(sender As System.Object, e As System.EventArgs) Handles nud_tratto.ValueChanged

        drawWidth = nud_tratto.Value
        P.Width = drawWidth

    End Sub

    Private Sub CPC_OnPickedColorChanged() Handles CPC.OnPickedColorChanged

        drawColor = CPC.PickedColor
        P.Color = drawColor
        B.Color = drawColor

    End Sub

End Class


--> Il metodo di disegno tiene traccia delle coordinate Mouse precedenti e integra il semplice disegno del "pennello" ( in questo caso una Ellipse ) con una linea, per assicurare un'ottima continuità al tratto. Le possibilità di definire pennelli e tratti sono infinite...

--> Grazie alla straordinaria varietà di GDI+, non ci vuole molto per capirne le possibilità di upgrade...

aggiornamento da 26-06-2011 a 17:52 di MarcoGG

Tag: vb.net
Categorie
Programmazione

Commenti