|
Following is the piece of code i am using to render grayscale video onto screen. The pixel values are stored as 'int' in the variable disp_frame whose declaration is given below. 50 pixel buffers of size 176 X 144 is used.
I thought of creating bitmap out of these pixels and then use BitBlt to render it to the screen. But the CreateDIBSection is creating an exception when running in Debug code. It should be some syntax error. Could anyone debug it out.
int p=0,i=0,j=0,q=0;
extern int disp_frame[50][144][176];
///////////////////////
BITMAPINFOHEADER bmi;
BITMAPINFO bm;
RGBQUAD rgbarray[256];
bmi.biSize = sizeof(BITMAPINFOHEADER);
bmi.biWidth = 176;
bmi.biHeight = 144;
bmi.biPlanes = 1;
bmi.biBitCount = 8;
bmi.biCompression = BI_RGB;
bmi.biSizeImage = 0;
bmi.biXPelsPerMeter = 0;
bmi.biYPelsPerMeter = 0;
bmi.biClrUsed = 0;
bmi.biClrImportant = 0;
bm.bmiHeader = bmi;
for (int color_index = 0; color_index < 256; color_index++)
{
rgbarray[color_index].rgbBlue = i;
rgbarray[color_index].rgbGreen = i;
rgbarray[color_index].rgbRed = i;
rgbarray[color_index].rgbReserved = 0;
}
bm.bmiColors[1] = rgbarray[0];
/////////////////////
CRect rcClient;
GetClientRect(rcClient); // See Note 1
rcClient.right=176;
rcClient.bottom=144;
/*****************Doubtful routine starts here*******
HDC hDC;
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
HDC memDC = CreateCompatibleDC(hDC);
CreateDIBSection(hDC,bitmap,DIB_PAL_COLORS,ppbits,NULL,0);
HBITMAP memBM = CreateCompatibleBitmap(hDC,176,144);
SelectObject(memDC,memBM);
BitBlt(memDC,150,100,176,144,hDC,0,0,SRCCOPY);
|
|
|
|
|
jossion wrote: CreateDIBSection(hDC,bitmap,DIB_PAL_COLORS,ppbits,NULL,0);
What is "bitmap"?
A BITMAPINFO has a BITMAPINFOHADER in it. It also has 1 of the 256 RGBQUAD
structs you need already in it. You need to allocate this all in one contiguous section
of memory.
The initialization of the color table is wrong, unless you want all black.
This line is all wrong and useless - "bm.bmiColors[1] = rgbarray[0];"
You are rendering in the wrong direction, unless you're trying to copy pixels from that DISPLAY dc to a memory dc.
That "DISPLAY" DC ... why not just use the DC for the client area of a window?
You should use DIB_RGB_COLORS when creating the dibsection so the call doesn't overwrite your grayscale color table.
You never use the dibsection you create.
Something like this should help you create the DIBsection....I don't know what you're trying to render so I
can't provide an example for that until you clear that up ...
BITMAPINFO *bm = (BITMAPINFO *)new BYTE[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)];
bm->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bm->bmiHeader.biWidth = 176;
bm->bmiHeader.biHeight = 144;
bm->bmiHeader.biPlanes = 1;
bm->bmiHeader.biBitCount = 8;
bm->bmiHeader.biCompression = BI_RGB;
bm->bmiHeader.biSizeImage = 0;
bm->bmiHeader.biXPelsPerMeter = 0;
bm->bmiHeader.biYPelsPerMeter = 0;
bm->bmiHeader.biClrUsed = 0;
bm->bmiHeader.biClrImportant = 0;
for (int color_index = 0; color_index < 256; color_index++)
{
bm->bmiColors[color_index].rgbBlue = color_index; <font color="Green">
bm->bmiColors[color_index].rgbGreen = color_index; <font color="Green">
bm->bmiColors[color_index].rgbRed = color_index; <font color="Green">
</font> bm->bmiColors[color_index].rgbReserved = 0;
}
BYTE *pBitmapBits;
HBITMAP hBitmap = ::CreateDIBSection(NULL, bm, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0);
if (hBitmap)
{
<font color="Green">
::DeleteObject(hBitmap);
}
delete[] (BYTE *)bm;
Tell me what you want to do rendering-wise and I'll try to fill in the sample code.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I have pixel values of successive frames of video stored in int disp_frame[50][144[176], 50 buffers of size 176X144. Under a timer of 40ms I was doing all the stuff which i posted. Previously I was using setpixel to draw the video. Now for better speed I thought of doing BitBlt. So there came a ncessity to convert the raw pixel values to bitmap. That is what should happen in the rendering section. Creating DC,then Creating DIB then copying to memory DC, then using BitBlt or optional zooming with StretchBlt. I know that there are still excellent ways of doing it. But I thought of learning all techniques by coding it and seeing the performance. So I would like you to fill the rendering area with BitBlt(including routines for DC creation) for displaying pixels in disp_frame.As I have read the pixel values should be copied to (void**)&pBitmapBits. Basically I am not a person with programming background. that's why my code might have irritated you a bit. Anyhow a small apology for my mistakes.
bitmap is of type BITMAPINFO *bitmap.
|
|
|
|
|
First, your code didn't irritate me. You stated "Could anyone debug it out." and
I tried to do that.
Here's a breakdown of the rendering problem...
SetPixel is a really bad choice for rendering video, so moving to a bit-block-transfer
implementation is the right direction.
To use BitBlt()/StretchBlt(), you need a source DC with a bitmap containing the pixels
you want to render selected into it.
Since your pixel data comes in raw int format, you need a HBITMAP bitmap that allows you direct access
to its pixel data - thats what a DIBSection is for.
Once you have all that, there's more that can be optimized - You don't have to recreate the DIB section
every time you render a frame. It can be created once, before you start rendering frames.
Same applies to the memory DC - it only needs to be created once and have the DIBSection selected into it.
That means every 40ms, you only need to copy the pixel bits to the DIBSection, get a destination DC
for where you're going to draw, and blt.
Here's an expanded example...
<span style="color: Green;">
extern int disp_frame[50][144][176];
LONG VideoWidth = 176;
LONG VideoHeight = 144;
WORD BitsPerPixel = 8;
LONG BytesPerDIBSectionRow = (((VideoWidth * (long)BitsPerPixel + 31L) & (~31L)) / 8L);
BITMAPINFO *pBMI = 0;
BYTE *pBitmapBits = 0;
HBITMAP hDIBSection = 0;
HGDIOBJ hOldMemBitmap = 0;
HDC memDC = 0;
bool InitVideoRenderer()
{
pBMI = (BITMAPINFO *)new BYTE[sizeof(BITMAPINFO) + 255 * sizeof(RGBQUAD)];
pBMI->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pBMI->bmiHeader.biWidth = VideoWidth;
pBMI->bmiHeader.biHeight = VideoHeight;
pBMI->bmiHeader.biPlanes = 1;
pBMI->bmiHeader.biBitCount = BitsPerPixel;
pBMI->bmiHeader.biCompression = BI_RGB;
pBMI->bmiHeader.biSizeImage = 0;
pBMI->bmiHeader.biXPelsPerMeter = 0;
pBMI->bmiHeader.biYPelsPerMeter = 0;
pBMI->bmiHeader.biClrUsed = 0;
pBMI->bmiHeader.biClrImportant = 0;
for (int color_index = 0; color_index < 256; color_index++)
{
pBMI->bmiColors[color_index].rgbBlue = color_index;
pBMI->bmiColors[color_index].rgbGreen = color_index;
pBMI->bmiColors[color_index].rgbRed = color_index;
pBMI->bmiColors[color_index].rgbReserved = 0;
}
hDIBSection = ::CreateDIBSection(NULL, pBMI, DIB_RGB_COLORS, (void**)&pBitmapBits, NULL, 0);
if (hDIBSection)
{
memDC = ::CreateCompatibleDC(0);
hOldMemBitmap = ::SelectObject(memDC, hDIBSection);
return true;
}
else
{
delete[] (BYTE *)pBMI;
pBMI = 0;
return false;
}
}
void RenderFrame(int FrameIndex, HWND destwnd, int x, int y)
{
<span style="color: Green;">
BYTE *pCurDIBSectionRow = pBitmapBits;
for (int row = 0; row < VideoHeight; row++)
{
for (int col = 0; col < VideoWidth; col++)
{
pCurDIBSectionRow[col] = (BYTE)(disp_frame[FrameIndex][row][col] >> 24); <span style="color: Green;">
}
pCurDIBSectionRow += BytesPerDIBSectionRow;
}
<span style="color: Green;">
HDC ClientDC = ::GetDC(destwnd);
::BitBlt(ClientDC, x, y, pBMI->bmiHeader.biWidth, pBMI->bmiHeader.biHeight, memDC, 0, 0, SRCCOPY);
::ReleaseDC(destwnd, ClientDC);
}
void CleanupVideoRenderer()
{
if (hDIBSection)
{
::SelectObject(memDC, hOldMemBitmap);
hOldMemBitmap = 0;
::DeleteDC(memDC);
memDC = 0;
::DeleteObject(hDIBSection);
hDIBSection = 0;
delete[] (BYTE *)pBMI;
pBMI = 0;
}
}
<span style="color: Green;">
if (InitVideoRenderer())
{
RenderFrame(0, *this, 0, 0); <span style="color: Green;">
CleanupVideoRenderer();
}
*edit* fixed 32bpp source to 8bpp destination pixel data conversion
Last modified: 10hrs 52mins after originally posted --
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
thank you very much. This is the first time I am getting a complete solution from Codeproject. cheers.
|
|
|
|
|
No problem!
I just realized I treated your source data as 16bpp when it's 32bpp (int!) LOL I'll change that.
Cheers,
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi Salsbery,
For the past one year the piece of code you gave me satisfied my requirements excellently. Now I have come up with a problem of displaying colour video. I will need help once again in modifying the code to colour. The main problem is how I should arrange the pixels and where to write it. What are the BITMAPINFO parameters that I have to change. Hope to get a reply at the earliest.
|
|
|
|
|
jossion wrote: modifying the code to colour
How many bits per pixel?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
8 bit per pixel in RGB format
|
|
|
|
|
I'm experiencing a wierd problem when capturing a screen from within a desktop app running on terminal server.
Here's my code:
Public Shared Function CaptureControlImage(ByVal pControl As Control, Optional ByVal pstrFilename As String = "") As System.Drawing.Image<br />
' Returns the image contained with the referenced controls client rectangle and optionally saves it to JPEG file<br />
<br />
Dim g As Graphics<br />
Dim picture As PictureBox<br />
Dim img As Image<br />
<br />
' Create a new PictureBox control. This is used to manipulate the captured bitmap<br />
picture = New PictureBox<br />
picture.Image = New Bitmap(pControl.ClientRectangle.Width, pControl.ClientRectangle.Height)<br />
<br />
' Create a GDI+ drawing surface based on the PictureBox control<br />
g = Graphics.FromImage(picture.Image)<br />
<br />
' BitBlt the screen image at the co-ordinates representing the referenced controls client rectangle<br />
' into the drawing surface, which is the PictureBox control<br />
g.CopyFromScreen(pControl.PointToScreen(New Point(pControl.ClientRectangle.X, pControl.ClientRectangle.Y)), _<br />
New Point(0, 0), _<br />
New Size(pControl.ClientRectangle.Width, pControl.ClientRectangle.Height))<br />
<br />
' Creates an image object from the PictureBox surface<br />
img = picture.Image<br />
<br />
If Not IsNothing(img) AndAlso pstrFilename <> String.Empty Then<br />
' Save the image to disk if required<br />
img.Save(pstrFilename, Drawing.Imaging.ImageFormat.Jpeg)<br />
End If<br />
<br />
Return img<br />
End Function<br />
It works just fine when running locally, but when the app is deployed on another server and it's access via terminal server, then this is what you get:
http://www.threefivefive.com/gallery/data/500/medium/capture_ts.jpg[^]
Can anyone tell me why?
|
|
|
|
|
Hi I have searched everywhere and cannot find a way to progamatically mirror the screen. What I need is to be able to look into a mirror at the screen and view it correctly. i.e Everything on the screen must be from right to left and not left to right. Thank you
|
|
|
|
|
Maybe this article will help you:
http://www.microsoft.com/middleeast/msdn/mirror.aspx[^]
you could copy the content of your screen to an image, flip this image and draw it back to the screen. no problem there, if you just want the screen to show everything mirrored. of course you won't be able to use the controls, since just the mirrored image is drawn back to the screen while the controls are still in their original place.
"I love deadlines. I like the whooshing sound they make as they fly by." (DNA)
modified on Thursday, February 28, 2008 5:43 PM
|
|
|
|
|
I want to ask one more thing that i am using this code ... where height is the Font height and startPoint_x and startPoint_y is the point where text is to be display
CsGL.OpenGL.GDITextureFont myGDITextureFont;
Font newFont;
newFont = new System.Drawing.Font("Microsoft Sans Serif", (float)height);
myGDITextureFont = new GDITextureFont(newFont, 'a', 'z');
GL.glTranslatef((float)startPoint_x, (float)startPoint_y, 0);
myGDITextureFont.DrawString(text);
and in this way text displayed but when i click on it it turns into solid bar .... What is the problem with this code ....
|
|
|
|
|
I am using C#, OpenGL and want to draw the Text on screen ... I went to OpenGL site and see the GLFont and other methods. Problem I face in these are:
They give Code in C++ that uses pointers and references that are not supported in C# and it call them as unmanaged code, i write unsafe modifier in front of it but other problem arises. So, these codes are not helpful unless they are in C# language.
if anyone know the method how to draw text in openGL or how to use C++ code in C# language then tell me .... I will be very pleased for your help ....
|
|
|
|
|
Yasir Nawazish Ali wrote: if anyone know the method how to draw text in openGL or how to use C++ code in C# language then tell me .... I will be very pleased for your help ....
one way[^]
another.[^]
_________________________
Asu no koto o ieba, tenjo de nezumi ga warau.
Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)
|
|
|
|
|
Your First Link is not working .... But thanks for the Reply
I want to ask one more thing that i am using this code ... where height is the Font height and startPoint_x and startPoint_y is the point where text is to be display
CsGL.OpenGL.GDITextureFont myGDITextureFont;
Font newFont;
newFont = new System.Drawing.Font("Microsoft Sans Serif", (float)height);
myGDITextureFont = new GDITextureFont(newFont, 'a', 'z');
GL.glTranslatef((float)startPoint_x, (float)startPoint_y, 0);
myGDITextureFont.DrawString(text);
and in this way text displayed but when i click on it it turns into solid bar .... What is the problem with this code ....
|
|
|
|
|
Hi,
I need to render bitmaps really fast with great performance.
Since I at the same time need to do other CPU demanding operations it is prefered if the rendering can be handled as much as possible by the graphics card. But the rendering must perform ok even if there is no 3D support in the graphics card.
I have tried several rendering methods without coming to a conclusion.
I have tried these methods:
MFC:
----------------------------
CDC::StretchDIBits
CDC::StretchBlt
CDC::BitBlt
GDI:
----------------------------
SetDIBitsToDevice
DirectDraw:
----------------------------
IDirectDrawSurface7::BltFast
DirectX 9
----------------------------
IDirect3DDevice9::SetTexture
IDirect3DDevice9::StretchRect
ID3DXSprite::Draw
One method is by far fastest on all three systems I have tested with.
The system setup is similar for all three, except for the graphics cards:
Windows XP. service pack 2
Intel Pentium D CPU 3.40 GHz, 2GB Ram
The graphic cards differ accordingly:
1. Matrox Millenium G550. 32MB
2. Intel 82915. 128MB
3. Geforce8600GT 256Mb
The by far fastest rendering method is "IDirectDrawSurface7::BltFast".
It is also the only method which is slowest on system 1 with the worst graphics card, and by far fastest on system 3 with the best card.
Many of the other methods are worst on system 3, with the best graphics card!
However, I'am not very happy with using an old method from DDraw7, when there should be methods which are faster and more optimized for new graphic cards in DirectX 9. Furthermore BltFast does not support resizing.
But which method is this, that is best optimized for new graphics cards but also has good performance on computers with old graphics cards? And how do I use it to get the best performance and to minimize CPU usage, while letting the GPU do the work when supported by the graphics card?
What my application does is:
Retrieving several video streams on the network in MJPEG and MPEG4 format. Decoding the video to device independent bitmaps and finally rendering the bitmaps to screen in either original size, upscaled or downscaled. (An optional solution is to handle the resizing manually).
So the method has to be good at resizing the image, and I don't think I need any time consuming dubbel buffering, since I always draw the pictures in the same size at the same place once started.
Thanks for all help!
|
|
|
|
|
I have an algorithm which generates random 2D terrain shapes which are similar to those seen in the "Worms" game landscapes.
With such random shapes, how do I apply a texture to such random "curvy" shapes?
The GDI+ texture examples I've seen apply to regular shapes like rectangles but didnt cover how to apply textures to irregular shapes.
|
|
|
|
|
Floodfill[^] with a pattern brush?
But who is the king of all of these folks?
|
|
|
|
|
hi guys,
i want to start my career in web development.
kindly send me your suggestions about Design according to MICROSOFT STANDARDS.
My task is basically screen designing if u can share web templates.
i hope i will get soon suggestion from your side.
u can send your suggestion here or me4uonly@live.co.uk
thanks
bye
__________________________________________________
|
|
|
|
|
And why would we do this? We'd be complicit in helping you defraud your employer because you can't do the job and yet you're getting paid to do it. Tell you what - you can pay MY company to do this for you.
Or do you think your employer will be very pleased that you've just advertised a site that needs redesigning and admitted that your company isn't up to the task. How about if we got in touch with whites-stationery and let them know? Do you think they'd be pleased?
|
|
|
|
|
Dear Pete,
Thank you very much for your remarks, well if it is against the law to show any company name here then i will delete this question from here. i gave this name here as an example. i am not going to work on this site.
Actually i need free ASP.NET templates because i am a student and i want to work on stationary web site.
if u can help me then just reply me.
i hope you will help me in this regard.
take care
good bye
__________________________________________________
|
|
|
|
|
Saqib Yaqub wrote: Actually i need free ASP.NET templates because i am a student and i want to work on stationary web site.
if u can help me then just reply me.
i hope you will help me in this regard.
Ah, so in other words your homework assignement is to design a website for a stationary store and you want us to do your homework for you?
Doing my part to piss off the religious right.
|
|
|
|
|
Why not just google for free website templates? There are hundreds of sites that supply them.
|
|
|
|
|
In the *graphics* forum ?
You seem very confused to me.
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|