duuuże bmpy GDI jak to przyspieszyć

duuuże bmpy GDI jak to przyspieszyć
Prim0
  • Rejestracja: dni
  • Ostatnio: dni
0

mam do przesuwania dość duże bmpy w formacie 32b wys96pix szer od 10000 do 50000pixeli

chodzi o to żeby je przesuwać w 4 kawałkach po określonym polu np tak

Kopiuj
               
 private void Form1_Load(object sender, EventArgs e)
        {
            imageSuper = new Bitmap("temp.bmp");
            totalW = imageSuper.Width;
        }

 private void PanelPaint(object sender, PaintEventArgs e)
        {//totalW to szer obrazka
            Bitmap buffer = new Bitmap(this.Width, this.Height);//1152x384
            using (Graphics g = this.panel1.CreateGraphics())
            {
                for (int i = 0; i < totalW; i++)
                {
                    g.DrawImage(imageSuper, 1152 - totalW + i, 288);
                    g.DrawImage(imageSuper, 2304 - totalW + i, 192);
                    g.DrawImage(imageSuper, 3456 - totalW + i, 96);
                    g.DrawImage(imageSuper, 4608 - totalW + i, 0);
                    if (i > totalW - 4608) { g.DrawImage(imageSuper, -2 * totalW + 4608 + i, 0); }
                    if (i > totalW - 3456) { g.DrawImage(imageSuper, -2 * totalW + 3456 + i, 96); }
                    if (i > totalW - 2304) { g.DrawImage(imageSuper, -2 * totalW + 2304 + i, 192); }
                    if (i > totalW - 1152) { g.DrawImage(imageSuper, -2 * totalW + 1152 + i, 288); }

                   // g.Save();
                    Thread.Sleep(10);
             

                }
            }
        }

Problem w tym że jest to stanowczo za wolne
kombinuje od pewnego czasu nawet z dx i xna ale tam są ograniczenia co do wielkości obrazów
a tak poza tym to jak to wrzucić do osobnego wątku żeby mi głównego nie zajmowało

Azarien
  • Rejestracja: dni
  • Ostatnio: dni
0

Nie dość że przy każdym Paint alokujesz nową bitmapę, to jeszcze jej nigdzie nie używasz. Wywal to buffer.

O co chodzi z tym Thread.Sleep(10) w pętli wewnątrz Paint? To ma być animacja jakaś czy coś?

Prim0
  • Rejestracja: dni
  • Ostatnio: dni
0

Tak dokładnie taka animacja tylko przy dużych plikach tnie.
a ten buffer został po poprzednie próbie zupełnie o nim zapomniałem

Prim0
  • Rejestracja: dni
  • Ostatnio: dni
0

Kilka małych upgradeów widocznie polepszyło działanie ale wierze że da się to zrobić płynniej

Kopiuj
         private void Form1_Load(object sender, EventArgs e)
        {
            
            using (Bitmap bitmap = new Bitmap("temp.bmp"))
                imageSuper = bitmap.Clone(new Rectangle(0, 0, bitmap.Width, bitmap.Height), PixelFormat.Format32bppPArgb);
            totalW = imageSuper.Width;
            this.SetStyle(ControlStyles.AllPaintingInWmPaint,true);
        }
        private void PanelPaint(object sender, PaintEventArgs e)
        {
            //Bitmap buffer = new Bitmap(this.Width, this.Height);//1152x384
            using (Graphics g = this.panel1.CreateGraphics())
            {
                for (int i = 0; i < totalW; i=i+2)
                {
                    g.DrawImageUnscaled(imageSuper, 1152 - totalW + i, 288);
                    g.DrawImageUnscaled(imageSuper, 2304 - totalW + i, 192);
                    g.DrawImageUnscaled(imageSuper, 3456 - totalW + i, 96);
                    g.DrawImageUnscaled(imageSuper, 4608 - totalW + i, 0);
                    if (i > totalW - 4608) { g.DrawImageUnscaled(imageSuper, -2 * totalW + 4608 + i, 0); }
                    if (i > totalW - 3456) { g.DrawImageUnscaled(imageSuper, -2 * totalW + 3456 + i, 96); }
                    if (i > totalW - 2304) { g.DrawImageUnscaled(imageSuper, -2 * totalW + 2304 + i, 192); }
                    if (i > totalW - 1152) { g.DrawImageUnscaled(imageSuper, -2 * totalW + 1152 + i, 288); }

                   // g.Save();
                    Thread.Sleep(20);
             

                }
            }
        }
Ola Nordmann
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 414
0

GDI się do takich rzeczy nie nadaje - nie wykorzystuje wsparcia sprzętowego.

Prim0
  • Rejestracja: dni
  • Ostatnio: dni
0

Wiem wiem wiem ale kilka innych sposobów już poległo.
XNA i jedyny wrapper od dx "D2DWrapper" którym udało mi się to wymalować - bo mają ograniczenia co do wielkości obrazków.
Dodam jeszcze że kombinowałem z wrapperem od avi chyba "AviFile" super działa z tym że limit zapisywanych plików to 4GB czyli około 2500klatek w moim przypadku nieskompresowanego filmu
a kompresja w tym wrapperze to konieczność dobrej znajomości fourcc o czym nie mam pojęcia.
Czy OpenGL ma jakieś ograniczenia co do wielkości obrazków ?
Czy jest jakiś przyjemny werapper do c#?
Właśnie sprawdziłem DXSharpa przy dł bmp ponad 8k pixeli się wysypuje

Azarien
  • Rejestracja: dni
  • Ostatnio: dni
0

Podziel obrazek na mniejsze kawałki i sklejaj podczas rysowania.

Prim0
  • Rejestracja: dni
  • Ostatnio: dni
0

Tą metodą próbowałem w DX
zamiast jeden długi (sklejony z wielu małych) przesuwałem kilkanaście lub dziesiąt małych
owszem można wtedy załadować sporą ilość ale wydajność spada drastycznie bo zamiast wyrysowywać 4 rec muszę wyrysować ich dużo więcej w jednej klatce

Ola Nordmann
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 414
0

Wydajność może spaść w dx, bo grafika ma więcej trójkątów do narysowania, ale przy 5000 trójkątów to jest nieodczuwalne, a co dopiero przy 50.

Jeśli chodzi o procek (GDI+) to liczy się przede wszystkim ilość pikseli do "przemalowania".

Azarien
  • Rejestracja: dni
  • Ostatnio: dni
0

GDI+ jest wystarczająco wydajne żeby przerysować cały ekran zachowując płynność animacji na dość kiepskim komputerze. tak, sprawdzałem. moim zdaniem sam sposób rysowania (pętla ze sleepem wewnątrz jednego zdarzenia Paint) jest zły.

Ola Nordmann
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 414
0

@Azarien A akceleracja sprzętowa dla GDI+ nie pojawiła się przypadkiem w 7 dopiero?

Azarien
  • Rejestracja: dni
  • Ostatnio: dni
1

Według Wikipedii

Windows 7 includes GDI hardware acceleration for blitting operations […] GDI+ continues to rely on software
rendering in Windows 7.

C# używa GDI+.
Co nie zmienia faktu, że GDI+ wystarcza do płynnej animacji.

Ola Nordmann
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 414
0

Płynna animacja na procesorze 1.8GHz na rdzeń, jednordzeniowy (takowy właśnie posiadam)... Ciekawe...

Grafiki o których mowa w temacie:

wys96pix szer od 10000 do 50000pixeli

zawierają w sobie od 960 000 do 4 800 000px. Jedno odświeżenie to w takim razie średnio 2 880 000px. Sleep ustawiony na 20ms co daje nam 50fps. 144 000 000 pikseli na sekundę - tak średnio.

Prim0
  • Rejestracja: dni
  • Ostatnio: dni
0

Witam

ta pętla ze slipem to też efekt pewnej ewolucji
mogę śmiało powiedzieć że stukanie z Timera było znacznie gorszym pomysłem
W nocy pobawiłem się SharpGl bardzo fajny ale nie do tego niestety

Azarien
  • Rejestracja: dni
  • Ostatnio: dni
0

Spróbuj bez pętli ale z Invalidate czy Repaint czy jak to się tam nazywa pod koniec painta.
Potrzebna jednak będzie synchronizacja czasu, bo prędkość rysowania zależeć będzie od komputera.

Ola Nordmann
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 414
0

Jak masz system niższy niż Windows 7 to spróbuj czegoś innego niż Graphics.

Jakoś nie udziela mi się przekonanie @Azarien'a, że takie rozwiązanie będzie działać płynnie.

Prim0
  • Rejestracja: dni
  • Ostatnio: dni
0

Z płynnością już jest znacznie lepiej
teraz jak Paint wrzucić do osobnego wątku albo bgw

Prim0
  • Rejestracja: dni
  • Ostatnio: dni
0

OK poradziłem sobie
Dzięki za wszystkie sugestie

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.