Solved

GDI: Do not redraw the window after each output

Posted on 2004-04-05
13
435 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 20 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
 

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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
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

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
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 learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

707 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

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now