Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

GDI: Do not redraw the window after each output

Posted on 2004-04-05
13
Medium Priority
?
452 Views
Last Modified: 2007-12-19
I have a matrix 512*512, containing a color value. I want to draw on the screen an image, where each pixel will be at the color, defined by my matrix. I mustn't pass by image, but only using directly GDI output to the screen. If I output all pixels one by one, the entire time of outputing 512^2 pixels is about 5 seconds. It seems that GDI redraws the window each time it outputs a pixel. I'm right, am I? How is it possible to redraw only once, at the end, when all pixels are set?

How Paint does? It also inputs each pixel, but it doesn't take much time?

Thanks,
MainMa
0
Comment
Question by:MainMa
  • 7
  • 6
13 Comments
 
LVL 6

Expert Comment

by:joghurt
ID: 10764027
No, it's SetPixel that is slow, not the redraw.

You should create a bitmap in the memory (don't worry, in fact you have only to create a bitmap header) and use bitmap drawing functions.

What kind of colour array do you have? RGB values on three bytes for each pixel, ARGB values on four bytes or do you have some indexed image?
0
 

Author Comment

by:MainMa
ID: 10767480
1. Were I right when I said that in fact, the window is redrawed each time I draw a pixel?
2. How does Windows do to output to the screen a bitmap created in memory? There must be some function in some Windows DLL which does it...
3. I had an idea of using bitmap images like you said, but I hadn't got too much information. Can you give an idea of something, which will output an image, built from array of RGB values?

Thanks,
MainMa
0
 
LVL 6

Accepted Solution

by:
joghurt earned 80 total points
ID: 10768336
1. No. If it were redrawn, you would have to begin the painting again, triggering another repaint, etc.
2. There are various functions in the Windows API dealing with bitmap operations. For your purpose see BitBlt, StretchBlt/StretchDIBits and SetDIBits.
3. It's quite easy. Supposing you have an array of RGB values. The pixels are organized by line, for example
0 1 2 3
4 5 6 7

LONG picWidth = ...;      // Image width in pixels, MUST be a multiple of 4.
LONG picHeight = ...;      // Image height in pixels.
void* picPtr = ...;           // Image data

BITMAPINFO bmi;
ZeroMemory (&bmi, sizeof (bmi));
bmi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
bmi.bmiHeader.biBitCount = 24;              // 24-bit image, you can specify 32 if you have 32-bit (A)RGB values in your array.
bmi.bmiHeader.biClrImportant = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biCompression = BI_RGB;   // On Win98/Me and Win2k/XP you can specify BI_JPEG and BI_PNG if you pass a jpeg or png image
bmi.bmiHeader.biWidth = picWidth;
bmi.bmiHeader.biHeight = picHeight;        // If it's positive: bottom-up bitmap, if it's negative: top-down bitmap
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biXPelsPerMeter = GetDeviceCaps (hDC, HORZRES) / GetDeviceCaps (hDC, HORZSIZE);
bmi.bmiHeader.biYPelsPerMeter = GetDeviceCaps (hDC, VERTRES) / GetDeviceCaps (hDC, VERTSIZE);
bmi.bmiHeader.biSizeImage = 0;             // Must be set to zero for BI_RGB images.

StretchDIBits (hDC, 0, picWidth, picWidth, -picWidth, 0, 0, picWidth, picPtr, &bmi, DIB_RGB_COLORS, SRCCOPY);
// Check documentation for parameters of StretchDIBits
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:MainMa
ID: 10769715
Help!
> void* picPtr = ...; // Image data
What type of variable must-it be? I tried to set a matrix "COLORREF Matrix[size][size];" but I can's see something correct on the screen (horisontal red/green/blue/black lines). If, instead of COLORREF I use int, the result is the same!
0
 
LVL 6

Expert Comment

by:joghurt
ID: 10770133
A COLORREF is 4-bytes large, so in this case you should change bmi.bmiHeader.biBitCount to 32. The same applies to "int".
Do you have any special reason for using COLORREFs for each pixel instead of 24-bit values? This latter one can be done by using a simple character (or BYTE) array in which the R, G and B bytes come after each other: R1, G1, B1, R2, G2, B2...
BYTE Matrix[size][size * 3];

Btw, how do you initialize this array?
0
 

Author Comment

by:MainMa
ID: 10772178
This is my new code:

----------------------------------------------------------------------------------------------------
BYTE Matrix[8][8*3];
// Fill some cells
void initialise()
{
      Matrix[0][0] = 255; Matrix[0][1] = 0; Matrix[0][2] = 0;
      Matrix[0][3] = 0; Matrix[0][4] = 255; Matrix[0][5] = 0;
      Matrix[0][6] = 0; Matrix[0][7] = 0; Matrix[0][8] = 255;
      Matrix[0][9] = 255; Matrix[0][10] = 255; Matrix[0][11] = 0;
}
[...]
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
      LONG picWidth = 8; // Image width in pixels, MUST be a multiple of 4.
      LONG picHeight = 8; // Image height in pixels.
      void* picPtr = &Matrix; // Image data
[...]
case WM_PAINT:
      StretchDIBits(hdc,
            10, 10, picWidth*20, picHeight*20,
            0, 0, picWidth, picHeight,
            picPtr, &bmi, DIB_RGB_COLORS, SRCCOPY);
[...]
----------------------------------------------------------------------------------------------------

OK, it works, but first, "Matrix[0][0] = 255; Matrix[0][1] = 0; Matrix[0][2] = 0;" gives a blue pixel instead of red one, green stays green, and blue becomes red. I can, of course, invert each time first and third values, but maybe this invertion is an error...
It seems to me that having BYTE Matrix[size][size*3]; is compicated to store an image. For example, when I would store 1024*1024 image, it will take too much time to the program to convert Matrix1[a][b][3] to Matrix2[a][b*3].
0
 
LVL 6

Expert Comment

by:joghurt
ID: 10772894
Sorry, it was my fault, not yours. Parameter order for the RGB macro is R, G, B but in the memory the byte order is reversed so it's B, G, R.

In my view Matrix1[a][b][3] and Matrix2[a][b*3] are equivalent in the memory. So you can use the first declaration if you prefer that one.
0
 

Author Comment

by:MainMa
ID: 10773675
Thank you, all works.
0
 

Author Comment

by:MainMa
ID: 10773919
Just another question: how can I load an image (a file) to Matrix1[a][b][3] (we suppose that the size of image is a*b)?
0
 
LVL 6

Expert Comment

by:joghurt
ID: 10774297
If you have a bitmap file, you don't have to do the above trick. A simple LoadImage will supply you with a HBITMAP that can be used for drawing. But that's another question.
0
 

Author Comment

by:MainMa
ID: 10774775
Yes, I know. But if i want precisely to load a file into a matrix, how can I do it?
0
 
LVL 6

Expert Comment

by:joghurt
ID: 10775252
Ask a new question. It has nothing to do with the current topic.
0
 

Author Comment

by:MainMa
ID: 10776835
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

772 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