Link to home
Start Free TrialLog in
Avatar of rayofunreal
rayofunreal

asked on

TextOut to Bitmap ?

Hi ALL !!!

I have a little problem... I have a BITMAPHEADER structure and Bitmap pixels painted to window with BltFast... Is here any way, to plot text directly to Bitmap pixels ? (Text out etc.. need DC from HBITMAP, but i haven't it.. I have pixels only.... And when I tryied to handle it, it was very slow...)...
Thanx !

I'm using C++ under 95/98/NT....
Avatar of datn
datn

Have you tried the simple Paint program that comes standard with windows. You can save whatever you have to the clipboard and alter and add text to it in Paint.
Hi..

 Just create a dc  say
 HDC hDC=GetDC(NULL);
Then
HBITMAP hOld=(HBITMAP) SelectObject(hDC,hBit);  <-- hBit y'r bitmap..
then use textout etc ..what u need..
and re-selecte the old one to it..
 u will have the desired pixels ..

                                                 best of luck !!!
Avatar of rayofunreal

ASKER

Sorry.... I have ONLY bitmappixel... I haven't HBITMAP... I need some like OpenGL functions..... I can initialize BITMAPHEADER struct... But only....

prog:

make BITMAP array (counted)

hDC=CreateDC...
BltFast(hDc,...,pixel array,bitmapheader); // I don't need hbitmap - it is too slow....



now I'm plotting fonts:
for (x=0;x<NumF;x++) {
  SelectObject.....
  .
  .
  .
  TextOut(...);
}

But this is far from good.... So, I need TextOut DIRECTLY to BitmapPixels (if is tehre any way)... Ofcourse I can use CreateBitmapIndirect, but this is more far from good....

  Thanx !!!

 





ray you might like to put this question in Windows programming...I think it'll get more attention

If not, try putting a 0 pts "advertizing" question in Windows question.  Include the URL to this question
You said you use BltFast ... Is it right that you're using DirectX?
If so, you can use IDirectDrawSurface3::GetDC() to get a DC for the surface, and then
you can simply call TextOut. It's really that simple.
If not, saneesh's answer is right. The fastest and easiest way(i think you'd need >200 lines to
take another way) is what he mentioned. It's really easy to set up a HBITMAP from a
BITMAPINFOHEADER.
a) Look in the MFC Fire sample application#
b) I could explain if you'd like
ofcourse, with DX it is easy... But it must work without it. BltFast is API function.... HBTMAP I can create, but it is verry slow, because I need ANOTHER bitmap each WM_PAINT....
Pls check the FIRE example, it creates for every frame a new HBITMAP, and its pretty
fast ...
does your bitmap has fixed properties (i.e.: width, height, planes etc.) ? if so, you may try to use only one ststic bitmap and then you don't need to create it every time.
ofcurse... I have X,Y,1 plane and 16/24/32 bpp.... I have BITMAPINFO header struct....

BUT: bitmap pixels in this struct is NOT defined, for it I must call SetDIBPixel fn (or something like this...). I I have more "msaks" here... So, the best way is direct output to pixels....
I am a little unclear as to what the question really is... either you want to get text straight from a BMP (in which case you'd need a program that utilizes OCR [optical character recognization]) or you want to make a BMP out of text for which i suggest (after the already-suggested Windows Paint program) the Paste Special command available from many programs. type out your text, highlight and copy or cut it, then choose paste special -> paste as picture or paste as windows bitmap.... I hope that helps but I'd think you would have already tried that.
Hi !

I'll try explaing it more.....

I have a PICTURE (this picture is calculated 50 times per second). For plotting it to a window I'm using BltFast. This functions need ONLY bitmap pixels (phyzical), size, bpp etc. Nothing more.

And: I want to DRAW text (for ex. TextOut(...)...). I can't use functions, which NEEEEEED some DC (I haven't BITMAP object, I have only pixels - array of bytes...).

So, is any way to plot text FIRECTLY to pixels ? (I can't create Bitmap objcect -> HBITMAP -> SelectObject -> TextOut from several reasons....)...

Thanx !
Take a look at DirectDraw. I don't think that there is any other way.
oh i understand now.. sorry, I have no recommendation, but I'm sure there must be a way to do it. good luck
There is a way throw OpenGL. But I need functionalyty on STANDARD instalation of NT/win95 :-(
Another possibility: If your text doesn't change in each frame, you could possibly
create a HBITMAP (temporary!) of the same size, select this bitmap (temporary!)
in a DC, paint your Text into the bitmap, and release the DC and the bitmap, only
keeping the bitmap pixels (lpvBits).
Then, perhaps using assembler, you could overlay this bitmap using OR/AND.
Of course, if your text changes all the time, this is too slow.
(OpenGL BTW is almost the slowest graphics library i've ever seen. The only
advantage it has is that it is powerful and platform-independent. But for this purpose,
OpenGL is overkill)
You're right...

But as I wrote, all temporary operations I need to process 50-times per socend - and belive, it is verry SLOW (especially for larger bitmaps)... (Window allways make local bitmap pixels copy)

OpenGL - yes.... But there is nice function I need - some like text out to bitmap :-(((
void *ppvBits_MyBitmap;
void *ppvBits_MyTextBitmap;

asm {
  push esi
  push edi
  mov edi,[ppvBits_myBitmap]
  mov esi,[ppvBits_myTextBitmap]
  mov ecx,(size of bitmap in bytes)/4
  mov edx,4
  loop1:
  mov eax,[esi]
  or [edi],eax
  add esi,edx
  add edi,edx
  loop loop1
  pop edi
  pop esi
}

After that, ppvBits_MyBitmap is merged with ppvBits_MyTextBitmap.

BTW: OpenGL is at least a hundred times slower that creating ONE TIME a memory DC
and a memory bitmap, and then blitting the memory bitmap into your text bitmap.
Why don't you believe this? The methods mentioned by all the comments here are
i think all possibilities. The only way left is that you paint your text by yourself :)


:o)

Ok... But problem is not here... The problem is in Creating DC and Bitmap.... This is slow :-( (please, take a look on http://MP3.musichall.cz/Pulse and find here link on OVE -> I need it for -> you'll see....).

This time I'm doing it something like you wrote:

prepare full bitmap

for (int t=0;t<Usestexts;t++) {

    clear tmp pixels,prpepare DC (font,size,col...),...
    TextOut(....)...
    convert from DC to pixels
    plot bitnmap to my pixels (I'm using up to 16 layers of objects-so I need temp pixels)
}

BitBltFast(...)

I belive you openGL is slower, I don't want to use it. I only writes, that here is fn I need -> glTextOutToBitmap (I don;t remember right spelling)

Okay. Seems like we are misunderstanding each other.
Take a look at this piece of code:

// You only call this code *once* in your application, not per frame
// Please read the text below
typedef struct tagMemoryDC {
  HDC hDC; // handle to memory DC
  HBITMAP hBitmap; // handle to memory Bitmap
  int nSDC; // Result code from SaveDC(), see below
} MEMORYDC, *LPMEMORYDC;

void PrepareMemoryDC(int dx,int dy,LPMEMORYDC *lpmemDC)
{
  ASSERT(lpmemDC!=NULL);
  HDC wDC;
  // wDC only temporarily used
  wDC=GetDC(GetDesktopWindow());
  lpmemDC->hDC=CreateCompatibleDC(wDC);
  lpmemDC->hBitmap=CreateCompatibleBitmap(wDC,dx,dy);
  ReleaseDC(GetDesktopWindow(),wDC);

  // Now: Save DC's state, so we can select the objects we like
  // without getting a problem when releasing the DC again
  lpmemDC->nSDC=SaveDC(lpmemDC->hDC);
 
  // Select the HBITMAP into the memory DC
  SelectObject(lpmemDC->hDC,lpmemDC->hBitmap);
  // Now our memory DC is prepared
}

void ReleaseMemoryDC(LPMEMORYDC lpmemDC)
{
  ASSERT(lpmemDC!=NULL);
  // Restore initial DC state
  RestoreDC(lpmemDC->hDC,lpmemDC->nSDC);
  // Destroy DC
  DeleteDC(lpmemDC->hDC);
  // Destroy HBITMAP
  DeleteObject(lpmemDC->hBitmap);
  // Set both values to NULL
  lpmemDC->hDC=NULL;
  lpmemDC->hBitmap=NULL;
}

HDC AccessDC(LPMEMORYDC lpmemDC)
{
  ASSERT(lpmemDC->hDC!=NULL);
  return lpmemDC->hDC;
}

Now you have got this:
- an all-application lifetime valid memory DC
- an all-application lifetime valid memory Bitmap

To do this:
- Create a global variable of type MEMORYDC
- One-time initialize this variable using PrepareMemoryDC(desiredWidth,desiredHeight,                                                                                         &MEMORYDC-Variable);
- Access the DC throughout the application as often you like without creating and selecting
  again
- Put in your 'exit application' handling code a call to ReleaseMemoryDC()

So,
- you can obtain the bitmap bits using GetBitmapBits()
- and you can too paint into the bitmap using DC functions.

This is what you want i hope :)
Yes ! Thanx :-)

I'm going to try this....

Come for yours points Snegler ;-)
ASKER CERTIFIED SOLUTION
Avatar of snoegler
snoegler

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Me to :-) (As I wrote... I have no time now... I'm very busy :-(

L. Lostak aka Ray/Unreal

http://MP3.musichall.cz/Pulse
http://MP3.musichall.cz/IT3
http://MP3.musichall.cz/Unreal