[ Yu Raider @ 06.04.2006. 16:38 ] @
Dakle treba da izvucem ono sto se crta u PictureBox1_Paint eventu u sliku, tj image fajl...
Jeli to moguce?
[ Shadowed @ 06.04.2006. 16:57 ] @

PictureBox.Image.Save(Path)
[ Yu Raider @ 06.04.2006. 17:00 ] @
pbRadniProstor.Image.Save("c:\\a.bmp");

Daje error:

Code:

Object reference not set to an instance of an object.


???
[ akrosoft @ 06.04.2006. 17:08 ] @
Proveri da li ti je instnciran pbRadniProstor u momentu kada radis save.
[ Yu Raider @ 06.04.2006. 17:12 ] @
Instanciran? Mislis dal postoji :)... Da, postoji ako si to mislio... Da nije mozda to zato sto ne ucitavam nijednu sliku u njega?
Nego samo sve crtam pomocu _Paint eventa...
[ Shadowed @ 06.04.2006. 17:21 ] @
Ocigledno da nemas Image objekat. Ne bi bilo lose da das relevantan deo koda kojim crtas.
[ Yu Raider @ 06.04.2006. 17:28 ] @
U pravu si - nemam Image objekat, vec crtam sve u pbRadniProstor_Paint rucno:

Code:

        private void pbRadniProstor_Paint(object sender, PaintEventArgs e)
        {

            Pen SivaLinija = new Pen(Brushes.LightGray);
            Pen CrvenaLinija = new Pen(Brushes.Red);
            Pen PlavaLinija = new Pen(Brushes.Blue);
            Pen CrnaLinija = new Pen(Brushes.Black);

            Pen LinijaZaCrtanje = new Pen(Brushes.Transparent);
            
            Font ObičanFont = new Font("Arial", 12, FontStyle.Bold, GraphicsUnit.Point);
            StringFormat format = new StringFormat();
            format.Alignment = StringAlignment.Center;
            format.LineAlignment = StringAlignment.Center;

            int Brojac;
           

            CrvenaLinija.Width = 0.3f;
            SivaLinija.Width = 0.3f;
            PlavaLinija.Width = 4;
            CrnaLinija.Width = 4;

            if (Promenljive.MrežaUključena == true)
            {
                
                int VertikalnaRazdaljina = 10;
                int HorizontalnaRazdaljina = 10;

                if (edMrežaHoriz.Text != "" && edMrežaVert.Text != "")
                {
                    VertikalnaRazdaljina = int.Parse(edMrežaVert.Text);
                    HorizontalnaRazdaljina = int.Parse(edMrežaHoriz.Text);
                }
 
                e.Graphics.FillRectangle(Brushes.White, pbRadniProstor.Left, pbRadniProstor.Top, pbRadniProstor.Width, pbRadniProstor.Height);
                for (Brojac = 0; Brojac < pbRadniProstor.Height; Brojac += VertikalnaRazdaljina)
                {
                    e.Graphics.DrawLine(SivaLinija, 0, Brojac, pbRadniProstor.Width, Brojac);
                }

                for (Brojac = 0; Brojac < pbRadniProstor.Width; Brojac += HorizontalnaRazdaljina)
                {
                    e.Graphics.DrawLine(SivaLinija, Brojac, 0, Brojac, pbRadniProstor.Height);
                }
                
             

            }

            if (Promenljive.BrojProcesOblika != 0)
            {

                for (Brojac = 0; Brojac < Promenljive.BrojProcesOblika; Brojac++)
                {
                    
                    RectangleF privremenipravougaonik = new RectangleF();
                    privremenipravougaonik.X = Promenljive.ProcesOblik[Brojac].PozicijaX;
                    privremenipravougaonik.Y = Promenljive.ProcesOblik[Brojac].PozicijaY;
                    privremenipravougaonik.Width = Promenljive.ProcesOblik[Brojac].Širina;
                    privremenipravougaonik.Height = Promenljive.ProcesOblik[Brojac].Dužina;
                    e.Graphics.DrawString(Promenljive.ProcesOblik[Brojac].Tekst, ObičanFont, Brushes.Black, privremenipravougaonik, format);
                    if (Promenljive.ProcesOblik[Brojac].Izabran == true) { e.Graphics.DrawRectangle(PlavaLinija, Rectangle.Round(privremenipravougaonik)); e.Graphics.DrawImage(ListaSlika2.Images[2], Promenljive.ProcesOblik[Brojac].PozicijaX + 10, Promenljive.ProcesOblik[Brojac].PozicijaY - 10); }
                    else { e.Graphics.DrawRectangle(CrnaLinija, Rectangle.Round(privremenipravougaonik)); }
                   
                }

            }
               }
[ Yu Raider @ 06.04.2006. 17:58 ] @
Jooooj... Ima li mi pomoci? Ovo mi stvarno hitno treba...
[ Shadowed @ 06.04.2006. 18:16 ] @
Hm, nisam detaljno gledao sta se iscrtava ali sta mislis o tome da deklarises jedan globalni (na nivou klase) objekat tipa Bitmap, dodelis ga pbRadniProstor.Image-u i kreiras Graphics objekat iz njega. Napravis funkciju za crtanje i pozivas je kad ti treba (recimo pri tom Paint dogadjaju). Mozda ces cak i redje crtati jer ti slika ostaje kada se nesto nadje iznad PictureBox-a pa ukloni.
Onda mozes i izvrsiti i Save metodu.
[ Yu Raider @ 06.04.2006. 18:21 ] @
Razmisljao sam o tome, ali kada deklarisem nesto ko objekat Bitmap on trazi ime fajla... To me je zbunilo. Da li da stavim neki blank bitmap fajl?
[ Shadowed @ 06.04.2006. 18:29 ] @
Imas konstruktor koji prihvata Image objekat kao argument. Koristi pbRadniProstor.Image za to:
bitmap MyBitmap = new bitmap(pcbRadniProstor);

Mislim da je tako u C#-u
[ Yu Raider @ 06.04.2006. 18:32 ] @
Hm... To ne radi... Razlog:

Code:


Error    3    Argument '1': cannot convert from 'System.Windows.Forms.PictureBox' to 'string'    E:\backup\Ivan\DiagramPro\DiagramPro\GlavniProzor.cs    410    38    DiagramPro



Hehe ja sam kompletan noob .

Koristio sam bas to sto si napisao:

Code:

Image slika = new Bitmap(pbRadniProstor);


... samo sa drugim nazivima promenljivih...
[ Shadowed @ 06.04.2006. 18:48 ] @
Sorry, vidim da ti se zuri pa sam i ja pozurio. Trebalo je:

Image slika = new Bitmap(pbRadniProstor.Image)

Mada, sad mi pade na pamet da nece ici jer ti Image nije instaciran. Pogledaj u MSDN-u, imas i konstruktore gde prosledjujes dimenzije u pixel-ima i sl.
[ Yu Raider @ 06.04.2006. 18:50 ] @
Ima dosta konstruktora... Ali svaki trazi image file... Ustvari postoji i jedan koji trazi Graphics kao argument...
[ Yu Raider @ 06.04.2006. 18:53 ] @
Znam sta cu! Napravicu program iz jednog drugog prog jezika koji pravi bitmap, prazan bitmap, odredjenih dimenzija...

Ali moram da vas pitam: Kako se odavde runuje neki externi program, tj kojom komandom?
[ Yu Raider @ 06.04.2006. 19:03 ] @
Hm... Nece to moci tako... Napravio sam test - blank sliku, loadovao je u pbRadniProstor i pokusao da sejvujem, ali nista, slika je izasla bas onakva kakva je bila - bela!
[ Yu Raider @ 06.04.2006. 19:16 ] @
Pokusao sam i da stavim u pbRadniProstor_Paint() funkciju Crtaj() koja bi trebala da u Graphics objekat crta sve... Ali ne mogu da inicijalizujem Graphics objekat! Pri inicijalizaciji:

Code:

Graphics grafika = new Graphics();


mi izbaci da
Code:
Error    2    The type 'System.Drawing.Graphics' has no constructors defined    E:\backup\Ivan\DiagramPro\DiagramPro\GlavniProzor.cs    19    28    DiagramPro
[ Shadowed @ 06.04.2006. 19:29 ] @
Pogledaj http://msdn.microsoft.com/libr...awingbitmapclassctortopic5.asp
[ mmix @ 06.04.2006. 19:34 ] @
Nemoj me drzati za rec, ali mislim da bez BitBlt-a neces moci nista da uradis posto je GDI+ HDC koji koristis u tvom paint eventu screen HDC a ne memory HDC (uprosceno receno sve odmah ode na screen buffer, nista se ne cuva u objektnom svetu GDI+ pa da mozes da ga podignes/rekreiras nekako). Jedina opcija ti je da iskoristis BitBlt iz GDI+ (koji inace nije potpuno implementiran u .NETu) da sa screen HDCa iskopiras bitmapu u memorijski HDC odakle moze da se snimi.

Pogledaj code sample iz ove teme: http://www.elitesecurity.org/tema/162396/0#1056776

Taj code je predvidjen da sa screen buffera "mazne" sadrzaj kontrole. Samo umesto graph objekta iskoristi svoj graphics objekat iz paint eventa.

[ Yu Raider @ 06.04.2006. 19:48 ] @
Mmix - ovo radi ali ima veeeeeliki problem. A to je - nije ceo PictureBox vidljiv odjednom, nego sam ga strpao u panel sa scroll barovima...

@Shadowed

Dobro napravio sam bitmap :) Kako sad da uzmem sadrzaj samo PictureBoxa?
[ Shadowed @ 06.04.2006. 19:53 ] @
Uh. Pod pretpostavkom da su ti dimenzije Bitmap objekata odgovarajuce:
Code:

pbRadniProstor.Image=MyBitmap
Gprahics MyGraph = Graphics.FromImage(MyBitmap)


Sad taj MyGraph koristi za crtanje, a MyBitmap.Save() za snimanje fajla.

Ponavljam, nisam gledao detaljno kod za crtanje, ako je tacno ono sto kaze mmix (a ja mu verujem) dzaba ti.
[ dusans @ 06.04.2006. 20:00 ] @
Ako je tako onda ti lepo deklariši promenljivu za bitmap:
Code:

private Bitmap Bmp;


Zatim, u form load stavi ovaj kod:
Code:

this.Bmp=new Bitmap(this.pbRadniProstor.Width, this.pbRadniProstor.Height);


U paint eventu ovaj:
Code:

Graphics G = Graphics.FromImage(Bmp);
G.Clear(Color.Transparent);
// Dalje koristi za crtanje G umesto e.Graphics
// Npr. e.Graphics.DrawLine(SivaLinija, Brojac, 0, Brojac, pbRadniProstor.Height); 
// treba da bude G.DrawLine(SivaLinija, Brojac, 0, Brojac, pbRadniProstor.Height);

// Na kraju paint event-a ide ovaj kod da bi video u picture box-u ono što si upravo iscrtao
e.Graphics.DrawImageUnscaled(this.Bmp, 0, 0);


Kasnije snimanje je posle valjda jasno:
Code:

this.Bmp.Save(@"C:\Test.Bmp");


Pozdrav!

[Sad vidim da je Shadowed rekao istu stvar]

[Ovu poruku je menjao dusans dana 06.04.2006. u 21:02 GMT+1]
[ Yu Raider @ 06.04.2006. 20:06 ] @
Jeeeeeeeeeeeeee!!! Radi!!! Jeste da je program 90% sporiji iz nekog razloga ali barem radi . Hvala!!!!
[ Yu Raider @ 06.04.2006. 20:14 ] @
Hmmm cudno. Program je znatno sporiji iako usage procesora ne prelazi preko 50%. Ne bih sad da cepidlacim ali sto je veca slika tj njene dimenzije to radi sporije... jel to zbog

Code:

Graphics G = Graphics.FromImage(slika);


...?
[ dusans @ 06.04.2006. 20:19 ] @
Sporina dolazi iz ove linije ako je ti je PictureBox velik
Code:

e.Graphics.DrawImageUnscaled(this.Bmp, 0, 0);


Sad ako ne moraš da radiš iscrtavanje baš u Paint Event-u nego recimo na učitavanju forme ili na klik dugmeta onda možeš da dodaš u load event-u forme i liniju
Code:

pbRadniProstor.Image = Bmp;

A zatim tamo gde radiš iscrtavanje (ali nikako u PaintEventu) pozoveš sledeću liniju:
Code:

pbRadniProstor.Refresh();

Ovo će ti raditi dosta brže.

Pozdrav!
[ Yu Raider @ 06.04.2006. 20:21 ] @
Ne znam kako radi - ali nisam ni stavio tu liniju... I bez nje se iscrtava... A kada je stavim onda je jos sporije .
[ Yu Raider @ 06.04.2006. 20:23 ] @
Ah - naravno, pa ja sam u timeru od 50 ms radio refresh... Zato se i ispisuje ;).
Cek da probam tvoju varijantu.
[ Yu Raider @ 06.04.2006. 20:25 ] @
Tvoja varijanta : e.Graphics.DrawImageUnscaled(this.Bmp, 0, 0); mi uopste ne iscrtava na ekran :|. Oh well ako mora da bude sporo, sta da radim...
[ negyxo @ 07.04.2006. 10:37 ] @
Citat:

Oh well ako mora da bude sporo, sta da radim...


Ne mora da ide sporo. mmix ti je vec sve odgovorio. Treba samo da prebacis iscrtavanje u memory HDC a ne od kontrole. To ces uraditi tako sto ces kreirati prvo "kompatibilan" HDC na osnovu postojeceg a zatim sva ta iscrtavanja raditi na njemu a ne od kontrole. Na kraju na paint event samo uradis jedan BitBlt iz memory HDC u kontrolin HDC. Ovo je sigurno brze, valda :)

Evo zakacio sam mali primer. Vodi racuna samo da je ovo VS2005 projekat.



[Ovu poruku je menjao negyxo dana 07.04.2006. u 11:48 GMT+1]
[ Yu Raider @ 07.04.2006. 12:01 ] @
Jupiiiiiiiiiiiiiiiiiiiiiiiiiiiii!!! :D

HVALA SVIMA MNOGO!
[ Yu Raider @ 07.04.2006. 13:24 ] @
Hm... Jeste nekih 20 % brze ali je i dalje veoma sporo... Verovatno je to zbog samog crtanja, koje je jako glomazno i desava svaki frame.
[ mmix @ 07.04.2006. 13:29 ] @
Citat:
Yu Raider: Hmmm cudno. Program je znatno sporiji iako usage procesora ne prelazi preko 50%.


Ako imas P4 HT (Hyper Threading) ili jaci multi-core procesor onda ti single-thread aplikacija nikad nece uzeti vise od 50% ukupnog CPU vremena.
[ Yu Raider @ 07.04.2006. 13:31 ] @
I ne uzima, cpu ne ide preko 50%, ali je izvrsavanje mnogo sporo. Glupi .NET
[ mmix @ 07.04.2006. 13:38 ] @
Citat:
Yu Raider: Hm... Jeste nekih 20 % brze ali je i dalje veoma sporo... Verovatno je to zbog samog crtanja, koje je jako glomazno i desava svaki frame.


Jel ti to pravis neku GDI+ igricu? Ako pravis animaciju i hoces da bude glatka, onda je mozda pametnije da razmislis o 2D DirectX-u, narocito sto sad postoji .NET podrska. Taj DirectX.NET je spor stravicno kad su u pitanju prave 3D igirce, ali mislim da je vise nego brz za tvoje potrebe. GDI+ jednostavno nije predvidjen za takve stvari.





[ Yu Raider @ 07.04.2006. 13:43 ] @
Ne - nije igra. Nego Flowchart maker. ( http://en.wikipedia.org/wiki/Flowchart ) Radi zadovoljavajuce brzo kada ne iscrtavam mrezu,
koja treba da pokrije ceo radni prostor, ali kada treba mrezu da iscrtavam UZAS. Tad mi i strelica secka .

Inace kod koji koristim za crtanje mreze pri svakom Paint eventu je:

Code:

            for (Brojac = 0; Brojac < pbRadniProstor.Height; Brojac += VertikalnaRazdaljina)
            {
                grafika.DrawLine(SivaLinija, 0, Brojac, pbRadniProstor.Width, Brojac);
            }

            for (Brojac = 0; Brojac < pbRadniProstor.Width; Brojac += HorizontalnaRazdaljina)
            {
                grafika.DrawLine(SivaLinija, Brojac, 0, Brojac, pbRadniProstor.Height);
            }
[ negyxo @ 07.04.2006. 16:19 ] @
Pa jer bas moras na paint event da iscrtavas sve linije? Ako ti je ta mreza staticna zasto je onda ne nacrtas u memoriji pa je posle stalno samo kopiras. Na taj nacin ces i izbeci bespotrebno ponavljanje koje ti inace i usporava.
Ako si skinuo onaj primer probaj da zamenis DrawSomething f-ju sa ovim

Code:

int xDis = 5;
            int yDis = 5;
            
            Random rnd = new Random();
            Color c = Color.FromArgb(rnd.Next(255), rnd.Next(255), rnd.Next(255));

            Graphics g = Graphics.FromHdc(memHdc);
            g.Clear(Color.White);
            
            Pen p = new Pen(c);

            for (int i = 0; i < 10; i++)
            {
                for (int x = 0; x < pictureBox1.Width; x += xDis)
                {
                    g.DrawLine(p, x, 0, x, pictureBox1.Height);
                }

                for (int y = 0; y < pictureBox1.Height; y += yDis)
                {
                    g.DrawLine(p, 0, y, pictureBox1.Width, y);
                }
            }


Ovako ce ti se DrawSomething iscrtati grid samo jednom u memoriji i posle toga na paint eventu ostaje samo da se kopira taj sadrzaj u pictureBox. Ovako imas samo jedan BitBlt naspram n poziva DrawLine.