![]() |
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! |
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.
|
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 |
AW: BMP Farbtiefe reduzieren ohne Farbverlust, Palettenzugriff
Guter Tipp, danke :)
|
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 +1. Es ist jetzt 16:29 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