Autor Beitrag
MKehrer
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 114

NT, 2000
D6
BeitragVerfasst: Di 11.11.03 09:05 
Hi Delphianer,

Ich hab ein Bitmap (24Bit) welches aber eigentlich nur ca. 20 unterschiedliche Farben hat. Umkopieren in ein 8Bit-Bitmap mit der entsprechenden Palette dauert sehr lange, obwohl ich bereits mit TBitmap.ScanLine arbeite.

Wenn man dann noch einen AVI-Film aus vielen Bitmaps basteln will und jedes Bild erst in ein 8Bit-Bitmap umkopiert dauert das ewig.

Kennt da jemand schnelle Routinen für das umwandeln 24Bit --> 8Bit ?

Manfred

_________________
Manfred
Was Du siehst ist in Dir (Smile)
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Di 11.11.03 19:58 
Hallo,

das kommt drauf an... ist die Plaette bekannt oder muss die jedesmal neu berechnet werden? Wenn du weißt, welche Farben es sein sollen, verwende doch diese Prozedur:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
{ Erzeugt eine 4Bit-Palette mit den in Colors angegeben Farben
  Wenn Colors weniger als 16 Farben enthält, werden die restlichen Farben
  auf schwarz gesetzt }

procedure CreatePalette4Bit(Bitmap: TBitmap; Colors: array of TColor);
var
  I: Integer;
  Palette: HPalette;
  LogPalette: PLogPalette;
begin
  // Bitmap auf 4Bit setzen
  Bitmap.PixelFormat := pf4Bit;

  // Speicher für Palette reservieren
  GetMem(LogPalette, SizeOf(TLogPalette) + 15 * (SizeOf(TPaletteEntry)));

  // Einstellungen setzen
  LogPalette^.palVersion := $300
  LogPalette^.palNumEntries := 16;

  // Alle Paletteneinträge auf 0 (schwarz) setzen
  ZeroMemory(@LogPalette^.palPalEntry[0], 16 * SizeOf(TPaletteEntry));

  // Farben setzen
  for I := 0 To High(Colors) do
  begin
    Colors[I] := ColorToRgb(Colors[I]);
    LogPalette^.palPalEntry[I].peRed   := Colors[I] and $FF;
    LogPalette^.palPalEntry[I].peGreen := Colors[I] and $FF00 shr 8;
    LogPalette^.palPalEntry[I].peBlue  := Colors[I] and $FF0000 shr 16;
    LogPalette^.palPalEntry[I].peFlags := 0;
  end;

  // Palette erzeugen
  Palette := CreatePalette(LogPalette^);

  // Bei Erfolg Palette zuweisen
  if (Palette <> 0then
    Bitmap.Palette := Palette;

  // Speicher freigeben
  FreeMem(LogPalette);
end;

Kannst das ganze noch in 8 Bit umschreiben.

_________________
Life is a bad adventure, but the graphic is really good!
MKehrer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 114

NT, 2000
D6
BeitragVerfasst: Mi 12.11.03 08:10 
Die Palette wird zu Beginn einmalig berechnet, dass dauert ca. ein paar ms.
Aber dann muß ich bei jedem Bild durch alle Pixel [ca. 600x600] durchrödeln.

Manfred

_________________
Manfred
Was Du siehst ist in Dir (Smile)
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Mi 12.11.03 13:42 
Hallo,

ja, dann passt mein code ja wie die faust auf's Auge - denn die Übernahme der Palette macht Windows in ein paar Millisekunden. Du übergisbt halt jedesmal die Palette, die du anfangs berechnet hast.

_________________
Life is a bad adventure, but the graphic is really good!
MKehrer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 114

NT, 2000
D6
BeitragVerfasst: Mi 12.11.03 13:47 
Danke,

ich probier´s mal
morgen geb ich bescheid

Manfred

_________________
Manfred
Was Du siehst ist in Dir (Smile)
MKehrer Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 114

NT, 2000
D6
BeitragVerfasst: Do 13.11.03 08:34 
Andreas Pfau hat folgendes geschrieben:
Hallo,

ja, dann passt mein code ja wie die faust auf's Auge - denn die Übernahme der Palette macht Windows in ein paar Millisekunden. Du übergisbt halt jedesmal die Palette, die du anfangs berechnet hast.


Windows verwendet aber nur ähnliche Farben!!

Also ich hab folgendes Vorgehen:
- erstellen einer Palette aus dem Quell-Bmp (24Bit aber nur ca. 20 Farben)
- erstellen eines Ziel-bmp (8Bit)
- Setzen der Palette des ZielBmp.
- Pixelweise umkopieren.

Beim letzen Punkt hab ich bemerkt, dass ich immer noch lesend auf Canvas.Pixels zugegriffen habe. Jetzt (über .ScanLine) geht´s schnell Genug.

Wenn ich den letzen Punkt ersetze durch bmp8Bit.Assign(bmp24Bit),
dann hab ich eben das Problem, dass Windows nur ähnliche Farben verwendet.

Weißt Du hier Abhilfe ?

Manfred

_________________
Manfred
Was Du siehst ist in Dir (Smile)
Currywurst
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 50

Win XP Pro
D3 Pro, D5 Std, D6 Pers
BeitragVerfasst: Do 13.11.03 08:53 
auf den efg seiten gibs reichlich infos zu sowas, evtl. hilft dir ja sogar das hier schon www.efg2.com/Lab/Gra...lors/ShowDemoOne.htm
Andreas Pfau
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 997



BeitragVerfasst: Do 13.11.03 16:04 
Hallo,

warum Pixelweise umnkopieren? Canvas.Draw()!!! Einhundertmillionenmal schneller...

_________________
Life is a bad adventure, but the graphic is really good!