Click here to Skip to main content
15,886,026 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am an OK coder but still novice with Visual Studio. I need to input a video image from a telemetry stream and display the bits. It seems that the tools include CreateDIBSection() and bitblt() will be the tools of choice. My questions are:

1) What type of project should I create to practice putting bits in a 100 by 100 array displayed on the screen. The code must be fairly fast. I can handle complex details in moving the data around, but working within Visual Studio is a challenge.

2) Do you know of any good and recent tutorials on this. Visual Studio 2008, Windows XP and Windows 7.
Posted

A DIBSection is the best way to create an image and have access to the bits. Why would you want to show the raw bits, and not the image ?
 
Share this answer
 
Comments
Member 7980135 10-Jul-11 22:12pm    
Because as the OP noted, the image arrives in a telemetry stream, one pixel at a time. The hardware extracts the pixels and my code must assemble the image, one pixel at a time. The final code will wait until an entire row has been received then display a row at a time.
Christian Graus 10-Jul-11 23:30pm    
OK, so you don't need to DISPLAY the bits, as raw data, but just build the image. The DIBSECTION is good for this, you will have a pointer where you can store the bytes as they arrive. You can show a partial picture by just making sure the rest of the bits represent a black image.
Create a Win32 Application or better create an MFC Application if you are familier with it

C++
#include <windows.h>
#define MAX_LOADSTRING 100
#define IDS_APP_TITLE L"Video Displayer" 
#define IDC_WIN32 L"ASIMPLEWINDOWCLASS"

HINSTANCE hInst;
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];

ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY 
_tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPTSTR lpCmdLine,int nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

	MSG msg;
	HACCEL hAccelTable;
	
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_WIN32, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);
	
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}
	
	while (GetMessage(&msg, NULL, 0, 0))
	{
	     TranslateMessage(&msg);
	     DispatchMessage(&msg);
	}
	return (int) msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon		= NULL;
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= NULL;
	return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;
   hInst = hInstance; 
   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
   if (!hWnd)
   {
      return FALSE;
   }
   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);
   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;
	switch (message)
	{
	
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: Do your drawing code here. Draw directly on main window.
                // When you would feel comfortable enough, create a seperate window class to handle all the video issues.  
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}


its a simplest windows program to create a window under visual studio.

Do your all drawing issues under MS_PAINT

You can research all the functions used here from msdn.....
 
Share this answer
 
v3
Comments
Mohibur Rashid 10-Jul-11 1:33am    
If you use this code create your application as win32 with empty project.

If you dont create an empty project you will get some default code with few more issue. such as a menu control
I created a Win32 console app, empty project and pasted in the example code.

LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WIN32, szWindowClass, MAX_LOADSTRING);


These two solicit the error: C2664:"LoadStringW" :cannot convert parameter 2 from 'const wchar_t[19] to 'UINT'

Disregarding that the code does not have LoadStringW, I look it up anyway and find:

int LoadStringW(
  UINT nID
) throw (CHeap_Exception);


This only has one argument. I don't know what it does.

Ok, so comment those two out and force some text into szTitle and szWindowClass as in:

szTitle[0] = 'V';
szTitle[1] = 'i';
etc


And presuming that if it works the console app window will not have a complete title. But LoadString may do something I don't detect.

Now the error is: LNK2019: unresolved external symbol _main referenced in function __tmainCRTStartup

I presume that

johny10151981 wrote:
Do your all drawing issues under MS_PAINT

is to be translate to WM_PAINT.
 
Share this answer
 
v2
1) I would get familiar with a simple dialog MFC application, the wizards usually mark off where you can override methods to get the code to do exactly what you want/need.

2) Learn to draw onto the screen with GDI for something basic like this. Follow any tutorial to get familiar with the topic. What you need to learn to do is create a compatible device context, draw what you need off the screen, then bit blit back to the currect device context. This is the method that's typically used for high speed graphics.

Search for GDI tutorials:
http://www.codeproject.com/search.aspx?q=GDI&sbo=kw[^]
http://www.toymaker.info/Games/html/gdi.html[^]
http://www.google.com/#sclient=psy&hl=en&site=&source=hp&q=drawing+with+gdi&aq=f&aqi=g1g-j1&aql=&oq=&pbx=1&bav=on.2,or.r_gc.r_pw.&fp=fce33a84b0764b22&biw=1760&bih=1006[^]
 
Share this answer
 
Regarding Solution 4: I don't have a reason to specify a dialog over an SDI, so I created an MFC project and specified SDI because I need only one image. If your perspective is different, please advise.

Once I get the bits going, I don't know where the image will be found. But one step at a time.

Here is what I have cobbled together. The debugger shows that my_bitmap ends up as zeroes as does the pointer ppbBits. GetLastError returns a zero indicating success. I am expecting bitmap to be non-zero along with the pointer.

const int IMAGE_ROW_COUNT    = 120;
const int IMAGE_COLUMN_COUNT = 120;
const int BYTES_PER_PIXEL    = 3;  // unknown, presume 3, one each RBG, change later
const int RGB_THREE_BYTES_PER_PIXEL = 24;
BITMAPINFO       my_bit_map_info;
BITMAPINFOHEADER my_bit_map_info_header;
RGBQUAD          my_rgb_quad;
HBITMAP          my_bitmap;
VOID            *ppvBits = NULL;
HDC              client_area_DC;
HDC              my_hdc;
DWORD           last_error = 3;

my_bit_map_info_header.biSize          = IMAGE_ROW_COUNT * IMAGE_COLUMN_COUNT * BYTES_PER_PIXEL;
my_bit_map_info_header.biWidth         = IMAGE_COLUMN_COUNT;
my_bit_map_info_header.biHeight        = IMAGE_ROW_COUNT;
my_bit_map_info_header.biPlanes        = 1;              // F1 help says must be 1.
my_bit_map_info_header.biBitCount      = RGB_THREE_BYTES_PER_PIXEL;
my_bit_map_info_header.biCompression   = BI_RGB;
my_bit_map_info_header.biSizeImage     = 0;     // per F1 help
                                                // but: http://www.codeguru.com/forum/printthread.php?t=456626
                                                // uses 256.
my_bit_map_info_header.biXPelsPerMeter = 0;     // Google found something that said always 0;
my_bit_map_info_header.biYPelsPerMeter = 0;
my_bit_map_info_header.biClrUsed       = 0;   // my guess
my_bit_map_info_header.biClrImportant  = 0;   // my guess

my_rgb_quad.rgbBlue     = 255;
my_rgb_quad.rgbGreen    = 255;
my_rgb_quad.rgbRed      = 255;
my_rgb_quad.rgbReserved = 0;

my_bit_map_info.bmiHeader    = my_bit_map_info_header;
my_bit_map_info.bmiColors[0] = my_rgb_quad;

client_area_DC = ::GetDC( NULL );
my_hdc =  CreateCompatibleDC( client_area_DC );

   // This is the key call.
my_bitmap = CreateDIBSection( 
      my_hdc, 
      my_bit_map_info,
      DIB_RGB_COLORS,
      ppvBits,
      NULL, 
      0 );

last_error = GetLastError();


Edit: the formatting mutilated the comments of the createdibsection call so I removed them and hoped for better readibility.
Edit: replaced [code] with <pre>
 
Share this answer
 
v3
I posted to tek-tips and ArkM discovered the problem.

my_bit_map_info_header.biSize = IMAGE_ROW_COUNT * IMAGE_COLUMN_COUNT * BYTES_PER_PIXEL
Does not get the size of the bitmap I want. It gets the size of the structure.
my_bit_map_info_header.biSize = sizeof( my_bit_map_info_header );

I find it curious that a fixed size structure needs its own length as one of its fields. But so be it. Now I start on my next step. All comments will be appreciated.
Thanks.
 
Share this answer
 
v3
1) To practice, use console application; also use it while developing you units: classes, implementation of algorithms.

2) Use MSDN. When this is not enough, Google for help in concrete topics.

Ask specific questions here at CodeProject. Make sure you provide really short code sample demonstrating your problem. Don't send big working code, develop code sample specially for asking a question. If some exceptions involve, dump it in some text file (don't forget Exception.Stack and all inner exceptions, recursively through Exception.InnerException; post the exception dump with your question, mark relevant code lines.

—SA
 
Share this answer
 
Comments
Mohibur Rashid 10-Jul-11 1:34am    
I cannot agree with your console application suggestion. Because you cannot draw in console application under Visual studio if i am not mistaken
Sergey Alexandrovich Kryukov 13-Jul-11 0:35am    
That is my point: learn basics before you come to drawing. If you have fun with drawing in the very beginning it might only delay your progress. Do not leave any voids in fundamental knowledge behind.
--SA
bkelly13 14-Jul-11 20:32pm    
Should I construe the two comments here as saying that I will not be able to get a bitmap and draw my pixels on the screen in a Win32_Console? Even though it does have the MFC hooks added in? Should I shift to an MFC project?
Sergey Alexandrovich Kryukov 19-Jul-11 1:06am    
What do you mean "you"? I'm talking to Member 7980135134. OP needs learning elementary topics. That's why bitmaps, drawing pixels on screen should be postponed -- there are important things to learn.
--SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900