Kreslení   zodpovězená otázka

VB.NET, WinForms, Grafika

Jak umožnit užavateli kreslit do pictureboxu, a potom obrázek uložit?

Děkujji za odpověď.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ukládání je jednoduché PictureBox má vlastnost Image, která je typu Image a má metodu Save() (nebo tak nějak podobně) pro uložení do nějakého běžného formátu.

Kreslení jako takové je pracnější a nevím o žádném jednodušším způsobu než o tom si to naimplementovat sám (přes události OnMouseMove, OnClick a další a pamatovat si nakreslené objekty buď jako bitmapu nebo jako vektory (což je jednodušší, neboť můžete využít aspoň GDI funkce pro kreslení čar, koleček atd) - tady ale doporučuju nevykreslovat přímo na PictureBox ale do BufferedGraphics objektu a pak to přes Render tam pláncnout celé, neboť je to rychlejší než vykreslování čáry po čáře přímo na monitor). Pokud někdo ví o nějakém jednodušším (předem naimplementovaném) způsobu, rád se poučím :)

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Už jsem to vyřešil ale potřebuji vědět, když mám kód pro nastavení čáry kterou kreslím (

 Dim drawWidth As Integer = TextBox1.Text ' šířka kreslené čáry 

) a ve form1_load : TextBox1.Text = "5", ukáže to chybu:

Při vytváření formuláře došlo k chybě. Podrobnosti viz Exception.InnerException. Chyba: Odkaz na objekt není nastaven na instanci objektu.

Co s tím?

A kód je takový (je to celé):


Public Class Form1
    Dim grp As Drawing.Graphics ' nabízí provádění grafických operací 
    Dim TBitmap As Drawing.Bitmap ' uložistě grafického obsahu tabule 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        TBitmap = New Bitmap(PicTabule.Width, PicTabule.Height) ' inicializujeme nový objekt Bitmap s velikostí tabule 
        grp = Graphics.FromImage(TBitmap) ' navážeme na TBitmap objekt grp, který umožní vykreslování 
        grp.Clear(Color.Black) ' nastavíme barvu tabule na černou 
        grp.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias ' aktivujeme vyhlazování čar 
        TextBox1.Text = "5"
    End Sub

    Private Sub PicTabule_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PicTabule.Paint
        ' vykreslíme obsah TBitmap na formulář do PicTabule 
        e.Graphics.DrawImage(TBitmap, 0, 0)
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        grp.Clear(Color.Black) ' smažeme tabuli 
        PicTabule.Invalidate() ' a překreslíme ji 
    End Sub
    Dim PosledniBod As Point ' bude potřeba si pamatovat poslední bod, kam se kreslilo 
    Dim drawWidth As Integer = TextBox1.Text ' šířka kreslené čáry 
    Dim drawColor As Color = Color.White ' barva štětce 
    Dim Kresleni As Boolean    ' aktivuje se stisknutím levého tlačítka na kreslící tabuli a indikuje začátek kreslení 

    Private Sub PicTabule_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PicTabule.MouseDown
        If e.Button = Windows.Forms.MouseButtons.Left Then
            PosledniBod = e.Location ' počátek kreslení je nyní nastaven jako pozice myši 
            grp.FillEllipse(New Pen(drawColor).Brush, New RectangleF(e.X - drawWidth / 2, e.Y - drawWidth / 2, drawWidth, drawWidth)) ' vykreslíme první bod (zakulacení počátku čáry) 
            PicTabule.Invalidate() ' nechame překreslit PicTabule 
            Kresleni = True    ' aktivujeme kreslici moc 
        End If
    End Sub

    Private Sub PicTabule_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PicTabule.MouseMove
        If e.Button = Windows.Forms.MouseButtons.Left And Kresleni = True Then
            grp.DrawLine(New Pen(drawColor, drawWidth), PosledniBod, e.Location) ' vykreslíme čáru z posledního bodu, kde byla myš 
            grp.FillEllipse(New Pen(drawColor).Brush, New RectangleF(e.X - drawWidth / 2, e.Y - drawWidth / 2, drawWidth, drawWidth)) ' vykreslíme zakončovací bod (zakulacení konce čáry) 
            PicTabule.Invalidate() ' nechame překreslit PicTabule 
            PosledniBod = e.Location ' poslední bod, ze kterého se kreslilo je nyní opět aktuální pozice myši 
        End If
    End Sub

    Private Sub PicTabule_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PicTabule.MouseUp
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Kresleni = False ' puštěním levého tlačítka myši opouštíme kreslící mód 
        End If
    End Sub
End Class

nahlásit spamnahlásit spam 0 odpovědětodpovědět

A když chci vybrat umístění přes savefile dialog?

kód:

   If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
            PicTabule.Image.Save(SaveFileDialog.FileName)
        End If

zobraazí se chyba:

Reference to a non-shared member requires an object reference.

A třeba:

PicTabule.Image.Save(Textbox1.Text)

Chyba:

Odkaz na objekt není nastaven na instanci objektu.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

PicTabule nemá nastavený žádný obrázek, pro ukládání použijte

If SaveFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK 
TBitmap.Save(SaveFileDialog.FileName)
Then
nahlásit spamnahlásit spam 0 odpovědětodpovědět
Dim drawWidth As Integer = TextBox1.Text

Tato chyba je způsobena tím, že textbox není inicializován. Stačí z této deklarace odstanit inicializaci a umísti jí do konstruktoru za volání metody InitializeComponent nebo do události formuláře OnLoad

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Koukám, že tady radí samí na slovo vzatí odborníci.

Problém je v tom, že chcete uložit PictureBox.Image, které je null, protože jej nepoužíváte. Kreslíte rovnou na Graphics onoho PictureBoxu. Pokud chcte výsledek uložit do souboru, někde ve Form_Load vytvořte Bitmap o velikosti PictureBoxu (bacha, je potřeba to dělat i v události ResizeEnd, kdy uživatel může měnit velikost okna) a kreslit do do Image, mělo by to vypadat asi takto:

'vytvořit novou bitmapu velikosti PictureBoxu
Dim b As New Bitmap(PictureBox1.Width, PictureBox1.Height)

'nastavit ji jako obsah PictureBoxu
If PictureBox1.Image IsNot Nothing Then PictureBox1.Image.Dispose()
PictureBox1.Image = b

'získat grafické plátno
Dim g As Graphics = Graphics.FromImage(b)
'kreslit
g.DrawLine...

'uložit obrázek
PictureBox1.Save("c:\obr.png")

Anebo ještě lépe mít onu bitmapu v nějaké proměnné v rámci Form1 (ne v proceduře) a v události Paint PictureBoxu ji přes DrawImage překreslit do toho PB, ale to už je skoro jedno.

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

Jsem víceméně nezkušený, nemůžete napsat kód?

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

k tomu nastavenní štětce(už tam mám nummericupdown z nazvem sirka)

Dim drawWidth As Integer = sirka.Value

nahlásit spamnahlásit spam 0 odpovědětodpovědět

chyba: Při vytváření formuláře došlo k chybě. Podrobnosti viz Exception.InnerException. Chyba: Odkaz na objekt není nastaven na instanci objektu.

a název chyby

InvalidOperationException was unhandled

nahlásit spamnahlásit spam 0 odpovědětodpovědět

A co jsem vám napsal? Dieselovou lokomotivu?

nahlásit spamnahlásit spam -1 / 1 odpovědětodpovědět

no... buď jsem to nepochopil nebo... no zkrátka tam nevidím ani zmínku o nastavení štece

nahlásit spamnahlásit spam 1 / 1 odpovědětodpovědět

Definujete drawWidth a chcete nastavit hodnotu z TextBoxu, když TextBox1 ještě není načtený.

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Díky, pokusím se něco udělat

nahlásit spamnahlásit spam 0 odpovědětodpovědět

Ano, předem jsem nastavil hodnotu na 5 a až potom jsem to měnil nudownem1

nahlásit spamnahlásit spam 0 odpovědětodpovědět
                       
Nadpis:
Antispam: Komu se občas házejí perly?
Příspěvek bude publikován pod identitou   anonym.
  • Administrátoři si vyhrazují právo komentáře upravovat či mazat bez udání důvodu.
    Mazány budou zejména komentáře obsahující vulgarity nebo porušující pravidla publikování.
  • Pokud nejste zaregistrováni, Vaše IP adresa bude zveřejněna. Pokud s tímto nesouhlasíte, příspěvek neodesílejte.

přihlásit pomocí externího účtu

přihlásit pomocí jména a hesla

Uživatel:
Heslo:

zapomenuté heslo

 

založit nový uživatelský účet

zaregistrujte se

 
zavřít

Nahlásit spam

Opravdu chcete tento příspěvek nahlásit pro porušování pravidel fóra?

Nahlásit Zrušit

Chyba

zavřít

feedback