Solved

save 24 bit mode screen to file in 8 bit mode

Posted on 1997-11-12
8
266 Views
Last Modified: 2010-04-04
My basic question is:

-the video card is in 16 or 24 bit mode,
-less than 256 colours are dispayed (some windows colours, some my own),

How can I save (part of) the screen to file in 8 bit mode?

The following approach gives the wrong colours (some kind of standard palette with a number of shades of a number of colours):

ScreenDC     := GetDc(0);
MemDc        := CreateCompatibleDc(ScreenDC);
MemBitmap    := CreateCompatibleBitmap(ScreenDC, SrcRect.width, SrcRect.height);
OldMemBitmap := SelectObject(MemDc, MemBitmap);

BitBlt(MemDC, ..., SrcDC, ...);  //SrcDC is the dc of the form

Then I fill a DIB info header with the format I want the bitmap: 1 plane, 8 bits per pixel

and then I call GetDIBits twice: the first time to get the colours into the header, and then to get the bits:

GetDIBits(MemDC, MemBitmap, 0, SrcRect.Height, nil,
      PBitmapInfo(pDibHeader)^, DIB_RGB_COLORS);

GetDIBits(MemDC, MemBitmap, 0, SrcRect.Height, pBits,
      PBitmapInfo(pDibHeader)^, DIB_RGB_COLORS);

After the first GetDIBits, the header does not contain my colours, but some sort of standard colour table, containing a couple of shades of every base colour. Saving the bitmap to file and viewing it with MS Paint indeed shows the wrong colours.
This approach works fine in 8 bit screen mode, but I need to handle screens in higher modes as well.

So my question is: what do I have to do to get the correct colours?

Wim
0
Comment
Question by:cadenza
8 Comments
 

Author Comment

by:cadenza
ID: 1350083
Edited text of question
0
 
LVL 5

Expert Comment

by:JimBob091197
ID: 1350084
Hi

Why not try the following:
procedure SaveDesktop;
var
    Bmp: TBitmap;
    DC: HDC;
begin
    Bmp := TBitmap.Create;
    DC := GetDC(0);
    Bmp.Width := Screen.Width;
    Bmp.Height := Screen.Height;
    BitBlt(Bmp.Canvas.Handle, 0, 0, Bmp.Width, Bmp.Height, DC, 0, 0, SRCCOPY);
    ReleaseDC(0, DC);
    Bmp.SaveToFile('C:\Temp\Desktop.bmp');
    Bmp.Free;
end;

If that doesn't work, try the following before Bmp.SaveToFile:
Bmp.PixelFormat := pf8bit;
(I think that PixelFormat will only work on Delphi 3...)

Regards,
JB
0
 

Author Comment

by:cadenza
ID: 1350085
Hi Jim Bob,

thanks for your suggestion.

1- if you let Delphi create a bitmap, it makes it compatible with the screen. So if your video card is in 24 bit mode, it makes a 24 bit bitmap. Saving this to file gives a 24 bit mode file.

2- pf8bit is Delphi 3. I use Delphi 2. (if this works in D3, which I think it does not, I would be very curious to learn how they do it).

I think my question boils down to: how can I make Windoze derive a proper RGB table (<= 256 entries) from the screen/a bitmap.

Wim
0
 
LVL 2

Expert Comment

by:greendot
ID: 1350086
Windows does not store "palettes" in any mode higher than 8-bit.  All pixels are stored in (R,G,B).  This is just a guess but you're probably going to have to create your own palette structure and translate the internal (R,G,B) pixels into palette mapped pixels.
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 1

Accepted Solution

by:
ergates earned 150 total points
ID: 1350087
I wrote some code to do this, to save GIF files from a 24bit bitmap. Essentially its what grrendot said.

The only way I have found to convert True Color bitmap to a palette based bitmap is to create a palette by going through every pixel and adding each new color to the palette, and setting the value in the destination bitmap to the palette index of the color.

Yep, its slow, one way to optimise is to remember last palette index when looking up a pixel, as adjacent pixels are often the same. Also if you have more colors in the source bitmap than entries in the palette, you will have to throw the lesser used ones away, and map them to similar colors, or dither.

Not easy.
0
 

Author Comment

by:cadenza
ID: 1350088
Hi Greendot & Ergates,

thanks for your comment/answer. I think I'll have to do what you say, but I thought of taking a shortcut about which I would like your (or anyone else's) opinion.

My advantage is: I know the colours that are present in the source: there are a couple of bitmaps of which I set the colours myself + some gray around it from the window's background + black and white. So do you think it would work if I loaded these colours into the RGB quad entries of the DIB header explicitly before calling GetDIBits to get the 8-bit pixels. In other words: is Windoze so clever to map the 24 bit pixels to the right indices of the colours in the header? If that would be the case, my problem seems to be solved, I guess.

Wim
0
 
LVL 1

Expert Comment

by:ergates
ID: 1350089
Unfortunately not, Windoze is not at all clever!
0
 

Author Comment

by:cadenza
ID: 1350090
That is a pitty, although it answers my question. I'll follow your approach and see if I can live with the speed. Maybe I can take advantage of the fact that I already know the colours used.. Or I simply force my users to switch to 8 bit colour :) .

thanks again for your answer,

Wim
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
This video discusses moving either the default database or any database to a new volume.
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

746 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

10 Experts available now in Live!

Get 1:1 Help Now