Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi BMP Farbtiefe reduzieren ohne Farbverlust, Palettenzugriff (https://www.delphipraxis.net/3555-bmp-farbtiefe-reduzieren-ohne-farbverlust-palettenzugriff.html)

cyborg 19. Mär 2003 00:20


BMP Farbtiefe reduzieren ohne Farbverlust, Palettenzugriff
 
Hallo Leute.

Ich will die Farbtiefe eines Bildes reduzieren aber wenn ich so vorgehe:

Bitmap.Pixelformat:=pf8bit;

habe ich zwar ein 256 Farben Bitmap, aber es gehen Farben verloren - obwohl die andere Bitmap (Format 32bit, 24bit u.a., das soll variabel sein, also auch mit 16 -> 256 und 256 -> 256 funktionieren!) insgesamt nicht mehr als 256 Farben hat!

Ich glaube da muss man die Palette optimieren.
Aber ich hab keine Ahnung wie das funktionieren soll...

leider finde ich keine eigenschaft in bmp, die mir einen (x,y) zugriff auf alle Paletteneinträge gibt, sonst könnte ich einfach die ersten 256 farben die ich im bitmap finde in ein array speichern (falls nicht schon drin) und hätte damit eine fertige palette.
das würde dann nur dann nicht funktionieren, wenn es mehr als 256 Farben in der bitmap gibt. aber das ist mir ja egal!

OregonGhost 19. Mär 2003 15:42

Du kannst die Bitmap ja mit CreateDIBSection (Windows-API) erstellen. Da kannst du dir die Farben wie du vorhast in ein Array packen. Wenn es dir nur um das Abspeichern der neuen Bitmap geht, reicht es sogar, die Bitmap gemäß dem PSDK-Artikel "Bitmap Storage" von Hand zu speichern.

cyborg 22. Mär 2003 23:23

Okay, nachdem die Hilfe nicht besonders viel gebracht hat (ich versuche die API soweit wie möglich nur im notfall zu benutzen, sonst könnt ich genauso C++ verwenden) habe ich es dennoch mit einem trick geschafft...:

frei nach meiner funktion wie ich es mache :cat:
Delphi-Quellcode:
//datentypen:
// BitmapXXbit = Bitmap mit 24, 32 usw. Bit
// Bitmap8Bit = Bitmap mit 256 Farben
// JPG = TJPegImage (uses jpeg!!) als utility
// Reduzieren der Bitmap Qualität mit dem Palette Optimizing von JPEG
Function BMPReduceTo8Bit(BitmapXXBit: TBitmap): TBitmap;
VAR
JPG: TJPegImage;
Bitmap8bit: TBitmap;

Begin
IF BitmapXXBit<>nil then begin
  JPG:=TJpegImage.Create;
  JPG.CompressionQuality:=100; // <--damit die bitmap nicht komprimiert wird
  JPG.Assign(BitmapXXBit); //<- BitmapXXBit -> JPG

  JPG.JPEGNeeded; // <-- verwandle in JPEG!
  JPG.PixelFormat:=jf8bit; // 8 bit reduzierung
  JPG.DibNeeded; // palette wird neu geschrieben, wieder bitmap fähig

  bitmap8bit:=TBitmap.Create;
  bitmap8bit.PixelFormat:=pf8bit;
  bitmap8bit.Assign(JPG); // JPG (8bit,opt.palette) -> BMP (8bit)
//  bitmap8bit.SaveToFile('whatever.bmp'); <-speichern

  JPG.Free;
 
  Result:=Bitmap8Bit;
end; // if %Bmp ned nil
end; // Proc %bmp8bit

MisterNiceGuy 28. Jul 2010 13:17

AW: BMP Farbtiefe reduzieren ohne Farbverlust, Palettenzugriff
 
Guter Tipp, danke :)

Medium 28. Jul 2010 14:11

AW: BMP Farbtiefe reduzieren ohne Farbverlust, Palettenzugriff
 
Ist allerdings mit Vorsicht zu genießen, da JPEG auf Qualität 100 nicht verlustfrei ist. Man muss mindestens mit den Rundungsfehlern durch das Hin- und Rücktransformieren in den anderen Farbraum, und den Frequenzraum rechnen, Farbunterabtastung findet, soweit nicht anders explizit gewählt, auch statt, und es wird auch auf 100 noch quantisiert.
Der Fehler fällt i.A. zwar sehr gering aus, und ist so gut wie nie wahrnehmbar, aber wenn man Exaktheit benötigt, ist das o.g. Verfahren ungeeignet. Gerade bei 8Bit Bitmaps ist JPEG so eine Sache, da die scharfen Kanten zwischen den Farben genau das sind, was JPEG als "loss" hin nimmt. Kommt noch Dithering ins Spiel, wird's ganz ekelig.

Der Weg über die API scheint mir in allen Belangen überlegen zu sein.


Alle Zeitangaben in WEZ +2. Es ist jetzt 22:27 Uhr.

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