duuuże bmpy GDI jak to przyspieszyć

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

               
 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

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ś?

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

0

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

         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);
             

                }
            }
        }
0

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

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

0

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

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

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".

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.

0

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

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.

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.

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

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.

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.

0

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

0

OK poradziłem sobie
Dzięki za wszystkie sugestie

1 użytkowników online, w tym zalogowanych: 0, gości: 1