Solved

GDI+ - refresh too slow

Posted on 2006-11-21
2
1,039 Views
Last Modified: 2012-08-13
Hi,

I have an application (managed c++) that works on two dimensional array of integers. Its size is user-defined, but let's assume it's 500x500. Each value represents different object - assume there are about 11 distinct values (0 - empty field and 1..10 - kinds of objects). I want to visualize it. So far I set up Graphics (g = this->CreateGraphics()) Pen (p) and SolidBrush (b) objects. Then I put loop
                         for(int i = 0; i < lattice->board->sizeX(); i++) {
                               for(int j = 0; j < lattice->board->sizeY(); j++) {
                                     if(lattice->board->getPlankton(i, j) != nullptr) {
                                          b->Color = lattice->board->getPlankton(i, j)->printColor();
                                          g->FillRectangle(b, offset_x + pix_size*i, offset_y + pix_size*j, pix_size, pix_size);
                                     }
                               }
                         }
Everything is neat and nice, as desired.

The problem is that this is simulation of integers in this array...when theirs quantity (!= 0) gets higher, refreshing image gets really slow. I can see how it goes column-by-column...and it's unacceptable for me.
I've already tried to set up double buffering with
                         this->SetStyle(static_cast<ControlStyles>(ControlStyles::DoubleBuffer |
                              ControlStyles::UserPaint |
                              ControlStyles::AllPaintingInWmPaint),
                              true);
                         this->UpdateStyles();
but this doesn't help me.

The questions are:
(1) what can I do to improve my performance?
or
(2) I do not insist on drawing it like that, I just need to have this array displayed in any way. Maybe there is better way to accompish that?

Thanks,
Grzegorz
0
Comment
Question by:GGuzdziol
2 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 500 total points
ID: 17989605
I suggest you the following idea: create array of bytes with length 500*500*3. Every 3 bytes in this array are one pixel in (B, G, R) order. Then fill this array by any way you need, setting individual pixel colors. Function BitsToBitmapRGB24 converts such array to Bitmap. You can draw bitmap in the form, or show bitmap in pixturebox.
In my code sample, I create array and fill it by some way. For example, first 250 lines are blue, other 250 lines are red. Replace this with your own code.

    using namespace System::Runtime::InteropServices;
    using namespace System::Drawing::Imaging;
    ...

    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
             {
                 array<Byte>^ bytes = gcnew array<Byte>(500*500*3);

                 // Fill array by some way
                 int current = 0;
                 for ( int line = 0; line < 500; line++ )
                 {
                     for ( int column = 0; column < 500; column++ )
                     {
                         // Fill pixel [line, column]
                         if ( line < 250 )
                         {
                             // Blue
                             bytes[current++] = 255;
                             bytes[current++] = 0;
                             bytes[current++] = 0;
                         }
                         else
                         {
                             // red
                             bytes[current++] = 0;
                             bytes[current++] = 0;
                             bytes[current++] = 255;
                         }
                     }
                 }

                 Bitmap^ bmp = BitsToBitmapRGB24(bytes, 500, 500);
                 pictureBox1->Image = bmp;
             }

             // Create RGB24 bitmap from Byte array
             Bitmap^ BitsToBitmapRGB24(array<Byte>^ bytes, int width, int height)
             {
                 if (bytes->GetLength(0) < width * height * 3)
                 {
                     return nullptr;
                 }

                 Bitmap^ bmp = gcnew Bitmap(width, height, PixelFormat::Format24bppRgb);
                 int i;

                 BitmapData^ data = bmp->LockBits(Rectangle(0, 0, bmp->Width, bmp->Height),
                     ImageLockMode::WriteOnly, bmp->PixelFormat);


                 if (data->Stride == width * 3)
                 {
                     Marshal::Copy(bytes, 0, data->Scan0, width * height * 3);
                 }
                 else
                 {
                     for (i = 0; i < bmp->Height; i++)
                     {
                         IntPtr p(data->Scan0.ToInt32() + data->Stride * i);
                         Marshal::Copy(bytes, i * bmp->Width * 3, p, bmp->Width * 3);
                     }
                 }

                 bmp->UnlockBits(data);

                 return bmp;
             }
0
 
LVL 14

Author Comment

by:GGuzdziol
ID: 17998095
Perfectly, master! :-)
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The following diagram presents a diamond class hierarchy: As depicted, diamond inheritance denotes when two classes (e.g., CDerived1 and CDerived2), separately extending a common base class (e.g., CBase), are sub classed simultaneously by a fourt…
In Easy String Encryption Using CryptoAPI in C++ (http://www.experts-exchange.com/viewArticle.jsp?aid=1193) I described how to encrypt text and recommended that the encrypted text be stored as a series of hexadecimal digits -- because cyphertext may…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question