Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi 8 bit Color Byte zu 24 bit Farbe umrechnen (https://www.delphipraxis.net/54060-8-bit-color-byte-zu-24-bit-farbe-umrechnen.html)

cyberblast 27. Sep 2005 10:36


8 bit Color Byte zu 24 bit Farbe umrechnen
 
Hallo Zusammen

Ich bin kurz vor der Verzweiflung. Versuche schon seit Stunden ein Byte zu einem 24 bit Farbwert umzurechnen.

Folgende Ausgangslage:

Ich habe ein Byte, sagen wird mal
Delphi-Quellcode:
b := $FF; //Weiss
In Wikipeida stand, es gibt 2 Varianten von 8 Bit Farbe, entweder mit Palette oder "True Color" durch umrechnung. In mienem Fall wird keine Palette benutzt.
Bei der Variante ohne Palette werden 3 Bits für Red, 3 Bits für Green und 2 Bits für Blau benutzt.

Kann mir jemand bei der Umrechnung helfen?

Hier einige weitere Beispiele:

Delphi-Quellcode:
//           B G  R
b0 := $AD; //10 101 101
b1 := $F6; //11 110 110
b2 := $FF; //11 111 111
b3 := $09; //00 001 001
b4 := $00; //00 000 000
Beim Beispiel für $FF müsste ich demnach für R 255, B 255 und G 255 erhalten.

Grüsse Martin

Kroko1999 27. Sep 2005 10:41

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Delphi-Quellcode:
function ColorByteTo24Bit (const AColor: Byte): TColor;
begin
  Result := Rgb ((AColor and $07) shl 5,
                 (AColor and $38) shl 2,
                 (AColor and $C0));
end;
wird zwar nicht ganz weiß, aber bei 3-3-2-Bit :?:

himitsu 27. Sep 2005 10:52

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
hmmm, mit der Berechnung wird dat nicht's Richtiges:
Delphi-Quellcode:
R := (C and $07) * 36.428571;
G := ((C shr 3) and $07) * 36.428571;
B := ((C shr 5) and $03) * 85;

Also bleibt dann noch der einfache Weg über 'ne Tabelle.

Entwerde du nimmst alle 256 Farbwerte in Eine auf, oder du erstellst nur kleine Tabellen, womit du dann jeden Farbwert inzeln berechnen kannst:
Delphi-Quellcode:
T3: Array[0..7] of Byte = (0, 36, ..., 219, 255);
T2: Array[0..3] of Byte = (0, 85, 170, 255);


R := T3[C and $07];
G := T3[(C shr 3) and $07];
B := T2[(C shr 5) and $03];

C24 := T3[C8 and $07]
  or (T3[(C8 shr 3) and $07] shl 8)
  or (T2[(C8 shr 5) and $03] shl 16);


[add]
@Kroko: andersrum gehts auch ... dann wird's aber net mehr ganz Schwarz ^^

Delphi-Quellcode:
Result := Rgb ((((AColor + 1) and $07) - 1) shl 5,
               (((AColor + 1) and $38) - 1) shl 2,
               ((AColor + 1) and $C0) - 1);

Flocke 27. Sep 2005 11:08

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Normalerweise löst man das über Bitwiederholungen:
Delphi-Quellcode:
function ColorByteTo24Bit (const AColor: Byte): TColor;
var
  R, G, B: Byte;
begin
  R := (AColor and $07) shl 5;
  G := (AColor and $38) shl 2;
  B := (AColor and $C0);
  Result := RGB(R or (R shr 3) or (R shr 6),
                G or (G shr 3) or (G shr 6),
                B or (B shr 2) or (B shr 4) or (B shr 6));
end;

DerDan 27. Sep 2005 11:12

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Wieso wirds mit einer Berechnung nix?

dass muss doch einwandfrei gehen!


einen 3 Bit Wert mit (255 / 7) zu multipizieren ergibt den entsprechenden 8 Bit wert !

DerDan

himitsu 27. Sep 2005 11:17

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
@DerDan: "nichts Richtiges" :zwinker:

klar wird dat was ... aber der "rechenaufwand" ist meiner Meinung nach nicht gerade angemessen.



@Flocke:
hmmm ... Bitwiederholung klingt och net schlecht

cyberblast 27. Sep 2005 12:49

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Herzlichen Dank für all eure Vorschläge!

Wie ich sehe geht dies auf Verschiedene X-Arten.
Ich habe ein Referenz-Bild angehängt, das erste Bild das ihr auf dem Gif sieht, beginnt mit $AD. Wenn ich den Colorpicker nehme, erhalte ich für diesen Wert 176, 176, 176

Diese Bilder befinden sich in einem Bildformat für Kenwood Autoradios. Leider haben die diverse Formate, eines davon ist dieses 8bit Bildformat. Leider kann ich auf dem Gerät nicht "Debuggen" ;-) und muss nun herausfinden wie dieses diese Pixel berechnet

Flocke 27. Sep 2005 13:01

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
In welchem Format schiebst du das Bild denn auf das Gerät? GIFs haben übrigens Paletten.

cyberblast 27. Sep 2005 13:23

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Das Format heisst KBM und wird wohl ein Kenwood eigenes Format sein.
Es hat einen 16-Bit grossen Header und ein paar Frames. Die einen Formate enthalten eine Palette, aber zu denen bin ich noch nicht gekommen.
Bin nun an dem Formaten die ohne Palette arbeiten. Bei einem anderen warens 1.5 Byte pixel, also 12bit, da musste ich einfach 0.5 bytes mal 16 rechnen und ich hatte den richtigen wert.
Aus den 8-bit Werten bin ich noch nicht ganz schlau geworden, sieht aber schon sehr ähnlich aus mit dem eurem Algorhytmus.

Und so siehts noch ein wenig besser aus:

Delphi-Quellcode:
procedure TForm1.Button4Click(Sender: TObject);
var
   ab : byte;
   r, g, b : byte;
begin
     ab := $FF;
     //10 101 101
     r := ab and $07 shl 5;
     g := ab and $38 shl 2;
     b := ab and $C0 + (ab and $01 shl 5);
     showmessage(inttostr(r));
     showmessage(inttostr(g));
     showmessage(inttostr(b));
end;

Flocke 27. Sep 2005 13:44

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Ich wollte eigentlich nur wissen, wie du das GIF-Bild erstellt hast - dafür hast du die Farben doch schon umwandeln müssen.


So kommst du nicht auf den vollen Wertebereich (bei deinen 4-Bit-Pixel übrigens auch nicht).

Code:
Gewollt:
0000 -> 00000000
1111 -> 11111111

Einfach x 16
0000 -> 00000000
1111 -> 11110000
Versuche mal den Vorschlag von DerDan oder die Bit-shr-or-Operation von mir oben, dann ist Weiß auch weiß!

Grishnak 27. Sep 2005 13:54

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Ist zwar ein anderes Forum :!: , aber hier findest du genau, was du suchst! :thumb:

cyberblast 27. Sep 2005 13:59

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Ja du hast recht, das war au käse von mir...Dachte ich habe eine Regel gesehen, das war leider nur bei dem Graustufen bild der fall.

Das Gif habe nicht ich erstellt, die waren als Vorschau da um zu sehen was in den KBM Dateien für bilder enthalten sind.

Das Format mit den 12 Bit Pixel ist für die Radios mit einem 4096-Farben Display. Diese habe ich bereits ausgelesen und umgerechnet, sind haargenau die selben Farben wie auf der Vorschau.

Daher denke ich, muss ich nur rausfinden wie sie die Pixel im 8bit modus errechnen. Das 8bit Format ist übrigens auch für den 4096-Farben Display.

DerDan 27. Sep 2005 13:59

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Zitat:

Zitat von himitsu
@DerDan: "nichts Richtiges" :zwinker:

klar wird dat was ... aber der "rechenaufwand" ist meiner Meinung nach nicht gerade angemessen.


Solange die Kiste Rechnen muss!
Und um ein paar mal ein Bild anzusehen.
Eine mathe Formel ist anschaulicher als Bit Schiebe Operationen!

Und sowieso:

Bevor man irgendetwas optimiert muss es erst mal funktionieren.
Wird oft genug anderst gemacht-> das Ergebnis ist dann zwar assig schnell, funktioniert aber nicht!


DerDan

cyberblast 27. Sep 2005 14:00

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
@Grishnak

Das war die 12Bit Variante ;-)

Flocke 27. Sep 2005 14:19

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Also auf den Wert 176 kommt man nur, wenn man den 8-Bit- in einen 12-Bit-Wert umwandelt und dann einfach x16 nimmt, also:

Delphi-Quellcode:
procedure TForm1.Button4Click(Sender: TObject);
var
  ab: byte;
  r, g, b: byte;
begin
  ab := $FF;
  r := 16 * ((( ab       and 7) * 15) div 7);
  g := 16 * ((((ab shr 3) and 7) * 15) div 7);
  b := 16 * ((((ab shr 6) and 3) * 15) div 3);

  showmessage(inttostr(r));
  showmessage(inttostr(g));
  showmessage(inttostr(b));
end;
Du solltest dann aber vielleicht mit einer CLUT (Color Lookup Table) arbeiten und diese bei der Initialisierung füllen.

Delphi-Quellcode:
var
  clut: array [byte] of TColor;

procedure InitClut;
var
  ab: byte;
  r, g, b: byte;
begin
  for ab := $00 to $FF do
  begin
    r := 16 * ((( ab       and 7) * 15) div 7);
    g := 16 * ((((ab shr 3) and 7) * 15) div 7);
    b := 16 * ((((ab shr 6) and 3) * 15) div 3);
    clut[ab] := RGB(r, g, b);
  end;
end;

himitsu 27. Sep 2005 14:22

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
@DerDan:
na funktionieren sollte es ja.

Und im Endefekt würde von den hier angebotenen Möglichkeiten wohl die mit dem Array, wo alle 256 Farben schon fertig umcodiert sind, wohl am schnellsten sein, da dort ja schließliech nur 1 bis 2 MOV-Operatioen nötig wären

Flocke 27. Sep 2005 14:25

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
... und wenn er's richtig schnell haben will und die Breite der Grafik glatt durch 4 teilbar ist, dann nimmt er einen TMemoryStream und schreibt

1. TBitmapFileHeader
2. TBitmapInfoHeader
3. die CLUT als Palette
4. die Bits seiner Bitmap

hinein, setzt Stream.Position wieder auf 0 und kann damit ein TBitmap.LoadFromStream machen :mrgreen:

cyberblast 27. Sep 2005 14:37

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Flocke

Bei deiner Berechnung werden folgende Bilder generiert: Siehe Anhang :-(

Flocke 27. Sep 2005 14:45

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Sind Fehlfarben :(
Variier mal die Bitbreiten:

Delphi-Quellcode:
r := 16 * ((( ab       and 3) * 15) div 3);
g := 16 * ((((ab shr 2) and 7) * 15) div 7);
b := 16 * ((((ab shr 5) and 7) * 15) div 7);
Delphi-Quellcode:
r := 16 * ((( ab       and 7) * 15) div 7);
g := 16 * ((((ab shr 3) and 3) * 15) div 3);
b := 16 * ((((ab shr 5) and 7) * 15) div 7);

DerDan 27. Sep 2005 14:45

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Zitat:

Zitat von himitsu
@DerDan:
na funktionieren sollte es ja.

Und im Endefekt würde von den hier angebotenen Möglichkeiten wohl die mit dem Array, wo alle 256 Farben schon fertig umcodiert sind, wohl am schnellsten sein, da dort ja schließliech nur 1 bis 2 MOV-Operatioen nötig wären

Was sicher stimmt, aber um die Tablle zu erstellen brauchst dann entweder ein extra Program
eine Routine die die Tabelle erstellt oder musst sie von hand ausrechnen.

kann man alles machen, sobald es funktioniert.

Und wehe man hat ein paar wenige Fehler in der Tabelle ...


mfg

Der Dan

cyberblast 27. Sep 2005 14:52

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Gibt folgende Variantionen:

Verzwickt :-(

Flocke 27. Sep 2005 14:58

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Sieht so aus :gruebel:

Gehen wir wieder zurück zur ersten Variante - probiere mal, die R, G und B jeweils paarweise zu vertauschen.

[Nachtrag]

wobei ich glaube, dass es nicht daran liegt.

Ich denke mal, die nehmen eine spezielle Palette.

cyberblast 27. Sep 2005 15:05

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Habe ich schon probiert, dabei werden die orangen vierecke blau respektive grün, die reihenfolge stimmt also...

Ich habe noch dieses probiert:

Delphi-Quellcode:

     r := ((AColor and $07) shl 1) * 16;
     g := ((AColor and $38) shr 2) * 16;
     b := ((AColor and $C0) shr 4) * 16;
     result := RGB(r, g, b);
Resultat siehe bild...

Flocke 27. Sep 2005 15:09

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Schickst du mir mal eins von diesen KBM-Dingern (oder die fünf vom Beispiel)...

cyberblast 27. Sep 2005 15:19

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Das erste Bild beginnt nach 16 Bytes, also beim 17.

Alle Bilder sind 16'384 bytes gross.

Bitte schalte den "Big Endian" modus ein im Hexeditor. Die Bytes sind vertauscht. Um die Word-Werte aus dem Header zu lesen habe ich die Swap funktion verwendet...

Olli 27. Sep 2005 15:41

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Sind die nicht normalerweise indiziert? Also so daß es eine Farbtabelle gibt mit Indeces von 0-255 und dann eben die Farbwerte in der Farbtabelle stehen? :gruebel:

cyberblast 27. Sep 2005 15:44

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Bei älteren KBM dateien für ältere Radios ist dies so...

Hier sind beie Varianten erwähnt:
http://en.wikipedia.org/wiki/8-bit_color

cyberblast 27. Sep 2005 16:06

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Ich glaube es muss was in diese Richtung sein...sieht schon fast identisch aus wie das original:

Delphi-Quellcode:
     r := ((ab and $07) shl 1) shl 4;
     g := ((ab and $38) shr 2) shl 4;
     b := (((ab and $C0) or (ab and $1) shl 5));

Flocke 27. Sep 2005 16:07

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Also wenn ich's hier ausprobiere, dann ist der Rotstich zwar nicht mehr so drastisch wie bei dir aber immer noch da.

Delphi-Quellcode:
procedure TForm1.LoadKBM(const Filename: string; Bitmap: TBitmap);
const
  kbmWidth = 256;
  kbmHeight = 5 * 64;
type
  TBitmapInfo8 = packed record
    bmiHeader: TBitmapInfoHeader;
    bmiColors: array [0 .. 255] of TRgbQuad;
  end;
var
  bfh: TBitmapFileHeader;
  bih: TBitmapInfo8;
  strm: TMemoryStream;
  fils: TFileStream;
  c, r, g, b: integer;
begin
  FillChar(bfh, SizeOf(bfh), 0);
  with bfh do
  begin
    bfType := $4D42;
    bfSize := SizeOf(bfh) + SizeOf(bih) + kbmWidth * kbmHeight;
    bfOffBits := SizeOf(bfh) + SizeOf(bih);
  end;

  FillChar(bih, SizeOf(bih), 0);
  with bih.bmiHeader do
  begin
    biSize := SizeOf(TBitmapInfoHeader);
    biWidth := kbmWidth;
    biHeight := -kbmHeight;
    biPlanes := 1;
    biBitCount := 8;
    biCompression := BI_RGB;
    biSizeImage := kbmWidth * kbmHeight;
    biClrUsed := 256;
  end;

  for c := 0 to 255 do
  begin
    b := 1 * ((( c       and 7) * 255) div 7);
    g := 1 * ((((c shr 3) and 7) * 255) div 7);
    r := 1 * (((((c shr 5) and 6) or ((c and 1) and ((c shr 3) and 1))) * 255) div 7);
    with bih.bmiColors[c] do
    begin
      rgbBlue := b;
      rgbGreen := g;
      rgbRed := r;
    end;
  end;

  strm := TMemoryStream.Create;
  try
    strm.WriteBuffer(bfh, SizeOf(bfh));
    strm.WriteBuffer(bih, SizeOf(bih));

    fils := TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite);
    try
      fils.Position := 16;
      strm.CopyFrom(fils, kbmWidth * kbmHeight);
    finally
      fils.Free;
    end;

    strm.Position := 0;
    Bitmap.LoadFromStream(strm);
    strm.SaveToFile(ChangeFileExt(Filename, '.bmp'));
  finally
    strm.Free;
  end;
end;
Man muss irgendwie das fehlende Bit in ROT so anpassen, dass es zu den anderen Farben passt - intern werden die wahrscheinlich eine dafür angepasste Palette nehmen.

Du kannst in dem Ausdruck
Delphi-Quellcode:
((c and 1) and ((c shr 3) and 1))
ein wenig herumspielen, um das fehlende Rot-Bit aus den anderen beiden zu holen.
Varianten:
Delphi-Quellcode:
((c and 1))
(((c shr 3) and 1))
((c and 1) or ((c shr 3) and 1))

cyberblast 27. Sep 2005 17:37

Re: 8 bit Color Byte zu 24 bit Farbe umrechnen
 
Ok, besten Dank für deine hilfe, ich hoffe ich krieg das noch hin dieses jahr ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:04 Uhr.

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