I know you can use TBitmap.PixelFormat to determine the number of colors
of an image, but this is "predefined" and we know the # of colors for
each bpp:
if Image1.Picture.Graphic is TBitmap then begin
case Image1.Picture.Bitmap.PixelFormat of //Find color depth
pf1bit : pf := '. Monochrome';
pf4bit : pf := '. 16 Colors';
pf8bit : pf := '. 256 Colors';
pf15bit: pf := '. 32768 Colors';
pf16bit: pf := '. 65536 Colors';
pf24bit: pf := '. 16 Million Colors';
pf32bit: pf := '. Gazillions of Colors!';
else
pf := '. Custom color scheme';
end;
end;
What I want to know is where do these numbers come from? What functions
are there to get these numbers? I'm thinking:
var
DeviceContext: hDC;
NumOfColors: integer;
MyBitmap: TBitmap;
{ Load bitmap into MyBitmap }
...
DeviceContext := GetDC(MyBitmap.Handle);
try
NumOfColors := GetDeviceCaps(DeviceContext, PLANES) *
GetDeviceCaps(DeviceContext, BITSPIXEL);
finally
ReleaseDC(hImage, DeviceContext)
end;
but that doesn't return the correct result. Can anyone enlighten me on
this? What is the formula for getting the number of colors of an image?
TIA,
Jon.
Basically
NumofColors := 1 shl GetDeviceCaps(DeviceContext, BITSPIXEL);
Ian.
Anyone else?
Jon.
Try changing your
DeviceContext := GetDC(MyBitmap.Handle);
to
DeviceContext := MyBitmap.Canvas.Handle;
GetDC returns a DC for a _window_, not a DC for a bitmap.
> Jon.
>
> Ian martin wrote:
>
> > > NumOfColors := GetDeviceCaps(DeviceContext, PLANES) *
> > > GetDeviceCaps(DeviceContext, BITSPIXEL);
> >
> > Basically
> >
> > NumofColors := 1 shl GetDeviceCaps(DeviceContext, BITSPIXEL);
> >
> > Ian.
--
David Ullrich
sig.txt still not found
function GetColorDepth(hImage: THandle): integer;
var
DeviceContext: hDC;
begin
DeviceContext := GetDC(hImage);
try
{testing various formulas)
Result := 1 SHL (GetDeviceCaps(DeviceContext, PLANES) *
GetDeviceCaps(DeviceContext, BITSPIXEL));
finally
ReleaseDC(hImage, DeviceContext);
end;
end;
Then I call this function like this:
var
MyBitmap: TBitmap;
NumOfColors: integer;
{ Load image into bitmap here. }
...
NumOfColors := GetColorDepth(MyBitmap.Canvas.Handle);
I've tried what you said and changed the function to:
function GetColorDepth(DeviceContext: THandle): integer;
begin
{ Test various formulas }
Result := 1 SHL (GetDeviceCaps(DeviceContext, PLANES) *
GetDeviceCaps(DeviceContext, BITSPIXEL)); { Returns
16M colors for any bitmap. }
//Result := 1 SHL GetDeviceCaps(DeviceContext, BITSPIXEL); { Returns 16M
colors for any bitmap. }
//Result := GetDeviceCaps(DeviceContext, PLANES) *
// GetDeviceCaps(DeviceContext, BITSPIXEL); { Returns
24 colors for any bitmap. }
end;
and call it the same way. Now it returns whatever # colors the comments say
for every bitmap, regardless of the bits. My desktop is set at 24-bit.
Could it be that it GetDeviceCaps is using my desktop instead of the bitmap's
handle?
Any other thoughts/advice?
TIA,
Jon.
Dude. If you want to know where these numbers come from, then
look at the VCL code that ships with Delphi Professional or
Delohi Client Server.
In short. these numbers come from:
1) If the source is a DIB (device independent bitmap) then the dibheader
contains the pixel format. You can write oodles of code to read your
own dib from various sources (file, clipboard, resource file, stream),
if you like. Its a good education. Start out with the WinAPI help file,
and the graphics functions related to bitmaps.
2) If the source is not a DIB, then the source is either monochrome
or the color depth of the screen.
One of the reasons that GetDeviceCaps is not working for you is that
you are working with a MemoryDC. MemoryDC are not devices, and this call
does not work well with all drivers when used with a memory dc.
Hope that helps!
Joe
--
Joe C. Hecht
http://home1.gte.net/joehecht/index.htm
if 8 bit, then Power(2, 8) = 256.
Does this sound correct for DIBs? if PixelFormat returns pfDevice, then we're
dealing with a DDB. Therefore the number of colors would be at what your
graphics card is set at. Am I getting this right?
I know I am a pain in the butt when dealing with graphics, but I have to start
learning somewhere.
Thanks,
Jon.
this version of the formula makes no sense - it's giving the
"right" answer only because PLANES happens to be 1. What you
actually want is PLANES * (1 SHL BITSPIXEL).
> //Result := 1 SHL GetDeviceCaps(DeviceContext, BITSPIXEL); { Returns 16M
> colors for any bitmap. }
> //Result := GetDeviceCaps(DeviceContext, PLANES) *
> // GetDeviceCaps(DeviceContext, BITSPIXEL); { Returns
> 24 colors for any bitmap. }
These last two are doing the same thing, right? Because
1 SHL 24 is 16M, and PLANES = 1.
> end;
>
> and call it the same way. Now it returns whatever # colors the comments say
> for every bitmap, regardless of the bits. My desktop is set at 24-bit.
> Could it be that it GetDeviceCaps is using my desktop instead of the bitmap's
> handle?
I can't tell exactly because of the parts you're leaving out - "load
image into bitmap" could mean various things, and the results will be different.
Assuming you're talking about D3 or higher, a TBitmap can be a DDB or a DIB.
If it's a DDB then you get the number of colors for your display - of it's
a DIB you should get something consistent with the value of PixelFormat.
Try explicitly _setting_ the value of PixelFormat before calling
your function. Immediately before.
.. but it will probably send you mad...
Colin
e-mail :co...@wilsonc.demon.co.uk
web: http://www.wilsonc.demon.co.uk/delphi.htm