Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi High Color --> TrueColor (https://www.delphipraxis.net/108783-high-color-truecolor.html)

Neutral General 19. Feb 2008 14:56


High Color --> TrueColor
 
Hi,

Ich versuche gerade einen 16-Bit HighColor Wert in eine 32-Bit TrueColor Farbe zu konvertieren. Aber irgendwas stimmt da was nicht.

Meinen Informationen zufolge ist eine 16-Bit Farbe so aufgebaut:

RRRRR GGGGGG BBBBB

Meine Funktion sieht so aus:

Delphi-Quellcode:
function HighColorToTrueColor(AColor: Word): TRGBQuad;
begin
  Result.rgbRed := ((AColor and $F800) shr 11) * Round(255/31);
  Result.rgbGreen := ((AColor and $07E0) shr 5) * Round(255/63);
  Result.rgbBlue := (AColor and $001F) * Round(255/31);
end;
Das müsste meinen Berechnungen zufolge auch hinhauen... Jetzt habe ich mir mal mit Photoshop ein pinkes 16-Bit Bitmap erstellt und im Hex-Editor geladen:

Pink (255 0 255): 1F 7C

IntToBin($1F7C) = 00011 111011 11100

Das kann aber ja nicht stimmen. Dieses Pink müsste ja dann eigentlich so aussehn:

11111 000000 11111

=> F8 1F

Jetzt bin ich etwas verwirrt :wiejetzt:

PS: Ach ja für $F81F liefert meine Funktion Pink, also funktioniert sie.

PPS: Wenn man die beiden Bytes umdreht:

:arrow: 0111110000011111

:arrow: Ok alles klar.. Antworten könnt ihr euch sparen :mrgreen:

Gruß
Neutral General

himitsu 19. Feb 2008 15:13

Re: High Color --> TrueColor
 
also wenn du schon mit reellen Zahlen arbeiten willst, dann wäre es wohl idealer das Round besser zu platzieren,
denn sonst hast du Probleme mit den oberen Farbbereichen.

:arrow: schau dir mal an, was deine Funktion bei WEIß zurückliefert

z.B.:
Delphi-Quellcode:
function HighColorToTrueColor(AColor: Word): TRGBQuad;
begi
  Result.rgbRed  := Round(((AColor and $F800) shr 11) * 255 / 31);
  Result.rgbGreen := Round(((AColor and $07E0) shr 5) * 255 / 63);
  Result.rgbBlue := Round( (AColor and $001F)        * 255 / 31);
end;
(wobei es ganz ohne reelle Zahlen bestimmt noch optimaler wäre)

Namenloser 19. Feb 2008 15:18

Re: High Color --> TrueColor
 
Imho hat eine 16-Bit-Farbe einen Alphakanal (wie 32-Bit ja auch), somit gäbe es also 4 Kanäle à 4 Bit.

//Edit: 16/4 ist 4 und nicht 8 :roll:

Muetze1 19. Feb 2008 15:25

Re: High Color --> TrueColor
 
Zitat:

Zitat von NamenLozer
Imho hat eine 16-Bit-Farbe einen Alphakanal (wie 32-Bit ja auch), somit gäbe es also 4 Kanäle à 4 Bit.

Nein, definitv nicht. Die Farben wurden auf 5, 5 und 6 Bit aufgeteilt, da mit man wenigstens ein wenig Farbspektrum ablegen kann. Bei deiner Aussage würde der Alphakanal ja schon ins lächerliche fallen, wenn der Farbbereich schon auf 12 Bit eingeschränkt wird.

15 Bit hat eine gleich grosse Farbraumverteilung 3x 5 Bit und 16 Bit hebt den Grünanteil auf 6 Bit an, weil das menschliche Auge in dem Farbspektrum sensitiver ist.

Ich habe noch nie, in den ganzen 19 Jahren wo ich programmiere, einen 16 Bit RGBA Wert gesehen. Ich lass mich aber gerne belehren.

shmia 19. Feb 2008 15:30

Re: High Color --> TrueColor
 
Man man einfach mit "and" die relevanten Bits ausschneidet und dann gleich richtig shiftet,
braucht man nicht mehr multiplizieren:
Delphi-Quellcode:
function HighColorToTrueColor(AColor: Word): TRGBQuad;
begin
  // RRRRRGGGGGGBBBBB
  // 00000000RRRRR000   => 8 nach rechts
  Result.rgbRed := (AColor and $F800) shr 8;

  // RRRRRGGGGGGBBBBB
  // 00000000GGGGGG00   => 3 nach rechts
  Result.rgbGreen := (AColor and $07E0) shr 3;

  // RRRRRGGGGGGBBBBB
  // 00000000BBBBB000  => 3 nach links
  Result.rgbBlue := (AColor and $001F) shl 3;
end;
PS: Bitte ausprobieren, ob das so richtig ist und dann in die Code-Library

Neutral General 19. Feb 2008 15:35

Re: High Color --> TrueColor
 
Zitat:

Zitat von shmia
Man man einfach mit "and" die relevanten Bits ausschneidet und dann gleich richtig shiftet,
braucht man nicht mehr multiplizieren:
Delphi-Quellcode:
function HighColorToTrueColor(AColor: Word): TRGBQuad;
begin
  // RRRRRGGGGGGBBBBB
  // 00000000RRRRR000   => 8 nach rechts
  Result.rgbRed := (AColor and $F800) shr 8;

  // RRRRRGGGGGGBBBBB
  // 00000000GGGGGG00   => 3 nach rechts
  Result.rgbGreen := (AColor and $07E0) shr 3;

  // RRRRRGGGGGGBBBBB
  // 00000000BBBBB000  => 3 nach links
  Result.rgbBlue := (AColor and $001F) shl 3;
end;
PS: Bitte ausprobieren, ob das so richtig ist und dann in die Code-Library

Naja ich glaube nicht das das richtig ist.

Delphi-Quellcode:
// RRRRRGGGGGGBBBBB
// 00000000RRRRR000   => 8 nach rechts
Result.rgbRed := (AColor and $F800) shr 8;
Wenn RRRRR = 11111 dann wäre der Rot-Farbanteil 100%. 31/31

RRRRR000 :arrow: 11111000. das wäre 248/255 (97,25%)

shmia 19. Feb 2008 15:47

Re: High Color --> TrueColor
 
Zitat:

Zitat von Neutral General
Wenn RRRRR = 11111 dann wäre der Rot-Farbanteil 100%. 31/31
RRRRR000 :arrow: 11111000. das wäre 248/255 (97,25%)

Ja, das stimmt natürlich.
Man könnte aber 2 Lookuptabellen mit 64 und mit 32 Byte bereithalten und sich damit die Multiplikation und Division sparen.
Delphi-Quellcode:

function HighColorToTrueColor(AColor: Word): TRGBQuad;
const LU_rot_blau:array[0..31] of Byte = (0,8,16,25,33,41,49,58,66,74,82,90,99,107,
115,123,132,140,148,156,165,173,181,
189,197,206,214,222,230,239,247,255);
const LU_gruen:array[0..63] of Byte =
(0,4,8,12,16,20,24,28,32,36,40,45,49,53,57,61,65,69,73,77,81,85,89,93,97,
101,105,109,113,117,121,125,130,134,138,142,146,150,
154,158,162,166,170,174,178,182,186,190,194,198,202,
206,210,215,219,223,227,231,235,239,243,247,251,255);
begin
  Result.rgbRed := LU_rot_blau[(AColor and $F800) shr 11];
  Result.rgbGreen := LU_gruen[(AColor and $07E0) shr 5];
  Result.rgbBlue := LU_rot_blau[(AColor and $001F)];
end;

OregonGhost 19. Feb 2008 16:02

Re: High Color --> TrueColor
 
Zitat:

Zitat von Muetze1
Ich habe noch nie, in den ganzen 19 Jahren wo ich programmiere, einen 16 Bit RGBA Wert gesehen. Ich lass mich aber gerne belehren.

Direct3D, Irrlicht und sicherlich auch viele andere Engines unterstützen die Formate X1R5G5B5 und A1R5G5B5, also je fünf Bit pro Farbkanal und ein Bit entweder ungenutzt oder als Alphakanal. 16 Bit muss also nicht notwendigerweise R5G6B5 sein, auch wenn das sicherlich das häufigste Format bei Bitmaps ist.

Muetze1 19. Feb 2008 19:05

Re: High Color --> TrueColor
 
Zitat:

Zitat von OregonGhost
Zitat:

Zitat von Muetze1
Ich habe noch nie, in den ganzen 19 Jahren wo ich programmiere, einen 16 Bit RGBA Wert gesehen. Ich lass mich aber gerne belehren.

Direct3D, Irrlicht und sicherlich auch viele andere Engines unterstützen die Formate X1R5G5B5 und A1R5G5B5, also je fünf Bit pro Farbkanal und ein Bit entweder ungenutzt oder als Alphakanal. 16 Bit muss also nicht notwendigerweise R5G6B5 sein, auch wenn das sicherlich das häufigste Format bei Bitmaps ist.

Joar, das ist auch sinnvoller als die von NamenLozer vermuteten 4 Bit für einen Alpha Kanal. Weil bei einem 4 Bit Alpha Kanal wäre ja der Farbraum total eingeschränkt. Ein Bit ist sinnvoller, wobei auch hier fraglich ist, was für einen "großen" Vorteil es hat, da der Alphakanal grundlegend nur 0% oder 100% sein kann bei einem Bit. Aber ich könnte mir vorstellen, dass man festlegen kann, dass ein Alphakanal von 0 = 25% ist und 1 = 80% o.ä. Also der Alphakanal hat nur zwei mögliche Werte.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:34 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz