# Board index » delphi » 15-bit-color value to TColor value

## 15-bit-color value to TColor value

Hi,
... how can I convert a 15-Bit color value (gggggbbbbbrrrr binary) to a
TColor value ?

## Re:15-bit-color value to TColor value

##### Quote
DPR <hw.del...@gmx.de> wrote in message

news:8isrd8\$ag35@bornews.borland.com...

##### Quote
> Hi,
>     ... how can I convert a 15-Bit color value (gggggbbbbbrrrr binary) to
a
> TColor value ?

function Convert15bitToTColor( C15: integer): TColor;
var
R, G, B: integer;
begin
{gggggbbbbbrrrrr }
R:= C15 and \$1F;
G:= (C15 shr 10) and \$1F;
B:= (C15 shr 5) and \$1F;
Result:= (R shl 3)+ (G shl 11)+ (B shl 19);
end;

## Re:15-bit-color value to TColor value

Your function does not work - just try to convert a white pixel (value
\$7FFF).
The result is \$F8F8F8 but should be \$FFFFFF.

Any idea ? DPR

## Re:15-bit-color value to TColor value

##### Quote
"DPR" <hw.del...@gmx.de> wrote in message news:8it7ro\$e485@bornews.borland.com...
> Your function does not work - just try to convert a white pixel (value
> \$7FFF).
> The result is \$F8F8F8 but should be \$FFFFFF.

Ah, but it is working correctly.  You can't get something out of nothing.

F = 1111 (four bits) + 8 = 1000 (one bit) = 5 bits.

The \$F8F8F8 answer still only has 15 bits of information.  That's
all you're starting with.  Your desired answer has 24 bits of information.
Where's the information about the remaining 3-bits to come from?
If you want \$FFFFFF instead of \$F8F8F8 that's extra information

Conversion from 24-bits to 15-bits requires throwing away
the least-significant 3-bits from each RGB color component.
In going the other direction, you start with 15 bits of information
and end up with 15 bits of information.  So you can see the
conversion from 24-bits to 15-bits and back to 24-bits
isn't exact.  However, 15-bits to 24-bits and back to
15-bits would be exact.

I hope this makes sense.

--
efg

Earl F. Glynn     E-mail:  EarlGl...@att.net
Overland Park, KS  USA

efg's Computer Lab:  http://www.efg2.com/Lab

## Re:15-bit-color value to TColor value

Earl,
Thanks for the assist.

function Convert15bitToTColor( C15: integer): TColor;
var
R, G, B: integer;
begin
if C15=\$7FFF then begin
Result:= clWhite {\$FFFFFF};
Exit;
end;
{gggggbbbbbrrrrr }
R:= C15 and \$1F;
G:= (C15 shr 10) and \$1F;
B:= (C15 shr 5) and \$1F;
Result:= (R shl 3)+ (G shl 11)+ (B shl 19);
end;

## Re:15-bit-color value to TColor value

Well let see here..
Mycolor := RGB(V and 31, (V shr 10) and 31, (V shr 5) and 31);
i think that is close.
##### Quote
DPR wrote:
> Hi,
>     ... how can I convert a 15-Bit color value (gggggbbbbbrrrr binary) to a
> TColor value ?

## Re:15-bit-color value to TColor value

##### Quote
> Earl,
>   Thanks for the assist.

> function Convert15bitToTColor( C15: integer): TColor;
> var
>   R, G, B: integer;
> begin
>   if C15=\$7FFF then begin
>     Result:= clWhite {\$FFFFFF};

But be aware this will affect other colors, too,
not just white.

For example, pure red in 15-bits would be
0111 1100 0000 0000 in binary, or \$7C00.

This becomes \$0000F8 in 24-bits, not
the \$0000FF that I think you're expecting.

--
efg

Earl F. Glynn     E-mail:  EarlGl...@att.net
Overland Park, KS  USA

efg's Computer Lab:  http://www.efg2.com/Lab

## Re:15-bit-color value to TColor value

of course it will be \$000000ff..

or else it's not max.red...

Limbique.

## Re:15-bit-color value to TColor value

ok, this is how to do it :
convert to 24 bit.   (tcolor = BGR)

r := value and 1F;
g := (value shr 5)  and 1F;
b := (value shr 10) and 1F;

NewColor := (r shl 3) or (g shl 11) or (g shl 19);

limbique.

##### Quote
DPR <hw.del...@gmx.de> wrote in message

news:8isrd8\$ag35@bornews.borland.com...
##### Quote
> Hi,
>     ... how can I convert a 15-Bit color value (gggggbbbbbrrrr binary) to
a
> TColor value ?

## Re:15-bit-color value to TColor value

Yes, of course the function works with all values - but not that way I want
it to work.
I just was puzzled by the fact that the Canvas.Pixels property returned
\$FFFFFF and not \$F8F8F8 (with a 15-bit-bitmap) - does that mean that the
Canvas.Pixels always returns a 24-bit color value ? And what happens if I
want to use a 32-Bit bitmap - I mean what does Canvas.Pixels will do then (I
haven't testet that yet).
So what to do, if I want to use a TColor value of a 15-bit bitmap within a
16/24/32-bit-bitmap ???
Isn't there a GDI function or macro available ? I don't want to loose color
information !
Let's say you have the 15-bit color with the following values (dec.) : R 15,
G 100, B 25.
If I want to have a 24-bit color now, the values are not 15-100-25 ??!!

Bye, DPR

## Re:15-bit-color value to TColor value

##### Quote
> Let's say you have the 15-bit color with the following values (dec.) : R
15,
> G 100, B 25.

max of 15bit   (r=5bit) = 31......  is that the problem?

## Re:15-bit-color value to TColor value

##### Quote
> max of 15bit   (r=5bit) = 31......  is that the problem?

No, was just a stupid example - let's say R = 29, G = 15, B = 10 okay ???

## Re:15-bit-color value to TColor value

##### Quote
"DPR" <hw.del...@gmx.de> wrote in message news:8iv68d\$aio4@bornews.borland.com...
> I don't want to loose color
> information !

I agree you don't want to loose information, but you can't get something for nothing.

If you start with 5 bits and want 8 bits, the "added" 3 bits are arbitrary -- there's
no information in those three bits.  You can decide to set these bits to 000 or you
could set them to 111.  Either decision is "correct" so you need to decide what you
want.

I have never studied exactly what Windows does when you take a pf15bit bitmap
and convert it to a pf24bit bitmap -- perhaps I should.

--
efg

Earl F. Glynn     E-mail:  EarlGl...@att.net
Overland Park, KS  USA

efg's Computer Lab:  http://www.efg2.com/Lab

## Re:15-bit-color value to TColor value

"Earl F. Glynn" <EarlGl...@att.net> wrote in message news:8ivona\$ehe4@bornews.borland.com...

##### Quote
> I have never studied exactly what Windows does when you take a pf15bit bitmap
> and convert it to a pf24bit bitmap -- perhaps I should.

To find out what's going on in convert 15-bit color to 24-bit color, let's look at the
shades of gray in 15-bit and see what they become in a 24-bit bitmap.

There are 32 shades of gray in 15-bit, RGB(index,index,index), where index = 0..31.
Here's how to create a display a pf15bit bitmap with these 32 shades of gray:

procedure TForm1.Button1Click(Sender: TObject);
TYPE
TRGBTripleArray = ARRAY[WORD] OF TRGBTriple;
pRGBTripleArray = ^TRGBTripleArray;
VAR
Bitmap :  TBitmap;
i      :  WORD;
j      :  WORD;
Pixel15:  WORD;
Row15  :  pWordArray;
Row24  :  pRGBTripleArray;
begin
Bitmap := TBitmap.Create;
TRY
Bitmap.Width  := 32;
Bitmap.Height := 32;
Bitmap.PixelFormat := pf15bit;

Memo1.Clear;

FOR j := 0 TO Bitmap.Height-1 DO
BEGIN
Row15 := Bitmap.Scanline[j];
Pixel15 := (j SHL 10) + (j SHL 5) + j;
IntToHex(j, 4) + ' ' +
IntToHex(Pixel15,4));
FOR i := 0 TO Bitmap.Width-1 DO
BEGIN
Row15[i] := Pixel15
END
END;

Image1.Picture.Graphic := Bitmap;

So defining these 32 shades of gray results with the following in the Memo box:

0 0000 0000
1 0001 0421
2 0002 0842
3 0003 0C63
4 0004 1084
5 0005 14A5
6 0006 18C6
7 0007 1CE7
8 0008 2108
9 0009 2529
10 000A 294A
11 000B 2D6B
12 000C 318C
14 000E 39CE
15 000F 3DEF
16 0010 4210
17 0011 4631
18 0012 4A52
19 0013 4E73
20 0014 5294
21 0015 56B5
23 0017 5EF7
24 0018 6318
25 0019 6739
26 001A 6B5A
27 001B 6F7B
28 001C 739C
29 001D 77BD
30 001E 7BDE
31 001F 7FFF

All of the above is as expected.
Conversion of  pf15bit to a pf24bit bitmap is easy with just one statement:

Bitmap.PixelFormat := pf24bit

BUT, if you let Windows (Delphi?) do this, the process is NOT
(Non-deterministic results like this are one reason not to trust Windows
and write your own code the produces consistent results.)

So the following code analyzes the 24-bit shades of gray from the
conversion of the pf15bit bitmap:

FOR j := 0 TO Bitmap.Height-1 DO
BEGIN
Row24 := Bitmap.Scanline[j];
WITH Row24[0] DO
BEGIN
IntToHex(j SHL 3, 2) + ' ' +
IntToHex(rgbtRed, 2) + ' ' +
IntToHex(rgbtGreen,2) + ' ' +
IntToHex(rgbtBlue,2))

END
END;

FINALLY
Bitmap.Free
END

Each line in the output below is like this:
<index> <"expected"><R><G><B>

One one machine, the results were:

15-bit shades of gray converted to 24-bits
0 00 00 00 00
1 08 08 08 08
2 10 10 10 10
3 18 18 18 18
4 20 21 21 21
5 28 29 29 29
6 30 31 31 31
7 38 39 39 39
8 40 42 42 42
9 48 4A 4A 4A
10 50 52 52 52
11 58 5A 5A 5A
12 60 63 63 63
13 68 6B 6B 6B
14 70 73 73 73
15 78 7B 7B 7B
16 80 84 84 84
17 88 8C 8C 8C
18 90 94 94 94
19 98 9C 9C 9C
20 A0 A5 A5 A5
22 B0 B5 B5 B5
23 B8 BD BD BD
24 C0 C6 C6 C6
25 C8 CE CE CE
26 D0 D6 D6 D6
27 D8 DE DE DE
28 E0 E7 E7 E7
29 E8 EF EF EF
30 F0 F7 F7 F7
31 F8 FF FF FF

On another machine the results were:
15-bit shades of gray converted to 24-bits
0 00 00 00 00
1 08 0F 0F 0F
2 10 10 10 10
3 18 1F 1F 1F
4 20 20 20 20
5 28 2F 2F 2F
6 30 30 30 30
7 38 3F 3F 3F
8 40 40 40 40
9 48 4F 4F 4F
10 50 50 50 50
11 58 5F 5F 5F
12 60 60 60 60
13 68 6F 6F 6F
14 70 70 70 70
15 78 7F 7F 7F
16 80 80 80 80
17 88 8F 8F 8F
18 90 90 90 90
19 98 9F 9F 9F
20 A0 A0 A0 A0
21 A8 AF AF AF
22 B0 B0 B0 B0
23 B8 BF BF BF
24 C0 C0 C0 C0
25 C8 CF CF CF
26 D0 D0 D0 D0
27 D8 DF DF DF
28 E0 E0 E0 E0
29 E8 EF EF EF
30 F0 F0 F0 F0
31 F8 FF FF FF

So you might get black (\$000000) and white (\$FFFFFF) the same
on both machines, but there still are some shades of gray that are
not identical across different machines.

When working on image processing projects, I would want code to
work the same on every machine, so I'd take a slower, predicatble
conversion over what is being done now.

--
efg

Earl F. Glynn     E-mail:  EarlGl...@att.net
Overland Park, KS  USA

efg's Computer Lab:  http://www.efg2.com/Lab

## Re:15-bit-color value to TColor value

##### Quote
> function Convert5bitsTo8Bits( byte: integer):byte;
> begin
>   case Value of
>      0: Result:= 0;
>      1..30: Result:= (Value shl 3)+8;
>      31: Result:= 255;
>   end;
> end;

Yes, that's exactly what I found out - take a look at the function I
created:

function ConvertC15To24(C15: Word): TColor;
var
R, G, B: Byte;
begin
R:= (C15 shr 10);
G:= (C15 and \$03E0) shr 5;
B:= (C15 and \$1F);
//
if (R = 31) then R:= \$FF else
if (R <> 0) then R:= (R+1) shl 3;
if (G = 31) then G:= \$FF else
if (G <> 0) then G:= (G+1) shl 3;
if (B = 31) then B:= \$FF else
if (B <> 0) then B:= (B+1) shl 3;
//
Result:= (B shl 16) + (G shl 8) + R;
end;

Go to page: [1] [2]