![]() |
Farbtabelle eines TBitmap bearbeiten?
Liste der Anhänge anzeigen (Anzahl: 1)
Irgendwie bin ich zu doof das zu finden, wie man sowas macht.
Im Prinzip wollte ich einfach nur schnell einen 4-Bit-Stream in Bitmap.Scanline kopieren und das als Graustufen sehen, ohne erst die Pixel einzeln umrechnen zu müssen, aber aktuell sieht das Bild dann sehr farbenfroh aus, selbst wenn ich vorher das Monochrom-Property setze. Inzwischen das Palette-Property entdekt, darüber mit dem Typ HPALETTE bei ![]() [EDIT] Grade nochmal nach "Delphi SetPaletteEntries" gesucht und ![]() * CreatePalette, ResizePalette, * SetPaletteEntries, * SelectPalette, RealizePalette Mal sehn ob dieser "nichtfunktionierende" Code nicht doch geht. :stupid: [EDIT2] Nee, ging nicht. Ich bekomm einen Datanstrom aus Bytes, mit 4 Bit pro Pixel in Graustufen, und den schiebe ich direkt in ein TBitMap, aber die farbliche Datstellung ... naja Der zweite Block ist das was aktuell als Testcode existiert.
Delphi-Quellcode:
var Bytes := FingerSensor.AcquireFingerImage;
var Width := Sqrt(Length(Bytes) * 2); meLog.Lines.Add(' Bytes: ' + Length(Bytes).ToString); meLog.Lines.Add(' ImageSize: ' + Width.ToString); imFingerImage.Picture.Bitmap.PixelFormat := pf4bit; imFingerImage.Picture.Bitmap.SetSize(Trunc(Width), Trunc(Width)); Move(Bytes[0], imFingerImage.Picture.Bitmap.ScanLine[imFingerImage.Picture.Bitmap.Height - 1]^, imFingerImage.Picture.Bitmap.Width * imFingerImage.Picture.Bitmap.Height div 2); const Grays: TArray<TColor> = [$00000000, $00111111, $00222222, $00333333, $00444444, $00555555, $00666666, $00777777, $00888888, $00999999, $00AAAAAA, $00BBBBBB, $00CCCCCC, $00DDDDDD, $00EEEEEE, $00FFFFFF]; var HPalette := imFingerImage.Picture.Bitmap.Palette; SetPaletteEntries(HPalette, 0, 16, (@Grays[0])^); //imFinger.Picture.Bitmap.Palette := HPalette; imFingerImage.Picture.Bitmap.Palette := SelectPalette(imFingerImage.Picture.Bitmap.Canvas.Handle, HPalette, True); //CreateHalftonePalette(DC: HDC) imFingerImage.Refresh; |
AW: Farbtabelle eines TBitmap bearbeiten?
Eventuell mal hier schauen:
![]() Die Palette in Bitmaps gilt (soweit ich mich erinnere) nur für 256-Farben-Bitmaps. ( ![]() Keine Ahnung, ob dashier entsprechend Deinen Wünschen funktionieren könnte (irgendwo aus meinem Fundus):
Delphi-Quellcode:
Oder bei der "Konkurenz":
procedure BitmapGrayscale(ABitmap: Graphics.TBitmap);
type PPixelRec = ^TPixelRec; TPixelRec = packed record B : Byte; G : Byte; R : Byte; end; var X : Integer; Y : Integer; Gray : Byte; Pixel : PPixelRec; begin for Y := 0 to ABitmap.Height - 1 do begin Pixel := ABitmap.ScanLine[Y]; for X := 0 to ABitmap.Width - 1 do begin Gray := Round((0.299 * Pixel.R) + (0.587 * Pixel.G) + (0.114 * Pixel.B)); Pixel.R := Gray; Pixel.G := Gray; Pixel.B := Gray; Inc(Pixel); end; end; end; ![]() |
AW: Farbtabelle eines TBitmap bearbeiten?
Wie gesagt, ich hab bereits ein Graustufenbild (dessen 36864 Bits) mit 4 Bit pro Pixel.
Aber ja, die Pixel einzeln zu kopieren ginge auch, aber das wollte ich möglichst vermeiden, wenn es direkt ginge. PixelColor = $00111111 * 4BitByte Mit Paint kann ich ja auch ein Graustufenbild als 4-Bit abspeichern und dann hat die Farbpalette nur noch bzw. mehr Grautöne. Somit kann PixelFormat = pf4bit das doch scheinbar. |
AW: Farbtabelle eines TBitmap bearbeiten?
Och menno, TBitmap.SetPixelFormat sagt, dass bei 4 Bit immer die Palette im SystemPalette16 überschrieben wird.
Delphi-Quellcode:
Gut, das ist eine globale in Vcl.Graphics und ich könnte die mal kurz austauschen,
Pal := FImage.FPalette;
case Value of // Copy Palette to prevent holding the same handle as SystemPalette16, // which would cause problems with the undetermined sequence of // finalizers in .NET pf4Bit: Pal := SystemPalette16; oder ich nehm erstmal den Code-Teil mit 4Bit von SetPixelFormat, zusammen dem Code der SystemPalette16 erstellt und versuch vor/statt dem PixelFormat:=pf4Bit das mit einer eigenen Palette, denn .Net kann mich mal. |
AW: Farbtabelle eines TBitmap bearbeiten?
Liste der Anhänge anzeigen (Anzahl: 1)
Mal überlegt, den Kram in ein TPNGImage zu schreiben? Die absolute Holzhammermethode wäre, bereits ein PNG der richtigen Größe mit der gewünschten Palette zu verwenden. Dann nur noch Datei (oder Ressource) öffnen und Scanline überschreiben. Beispiel ist angehängt.
Bei Problemen mit der Anzeige von Paletten-PNG siehe ![]() ![]() |
AW: Farbtabelle eines TBitmap bearbeiten?
Die Saftsäcke nutzen viele private Funktionen und die alle nachzubauen, das geht ja mal garnicht.
TBitmap.SetPixelFormat -> TBitmap.CopyImage, TBitMap.CopyPalette, TBitMap.CopyBitmap, ... Die Palette um das
Delphi-Quellcode:
auszutauschen hat funktioniert, aber wegen dem DeleteObject (ohne ist alles Schwarz) ist das auch keine schöne Lösung.
PixelFormat := pf4bit;
Delphi-Quellcode:
Ich hatte versucht mir aus TBitMap.CopyBitmap den Teil rauszuschnappen, der die Palette zuweist, wo ich am Ende bei SelectPalette und RealizePalette lande, also eigentlich was ich wollte, aber das ging nicht. (vermutlich irgendwo ein Fehler gemacht)
const Grays: TArray<TColor> = [$00000000, $00111111, $00222222, $00333333, $00444444, $00555555, $00666666,
$00777777, $00888888, $00999999, $00AAAAAA, $00BBBBBB, $00CCCCCC, $00DDDDDD, $00EEEEEE, $00FFFFFF]; var OldPal := Vcl.Graphics.SystemPalette16; var LogPal: TMaxLogPalette; LogPal.palVersion := $0300; LogPal.palNumEntries := 16; Move(Grays[0], LogPal.palPalEntry[0], 16*4); Vcl.Graphics.SystemPalette16 := CreatePalette(PLogPalette(@LogPal)^); try imFingerImage.Picture.Bitmap.PixelFormat := pf4bit; finally //DeleteObject(Vcl.Graphics.SystemPalette16); Vcl.Graphics.SystemPalette16 := OldPal; end; Also rein vom Code her kommt es wohl doch einfacher nur mit zwei Zeilen Code die Pixel einzeln zu kopieren. Dauert zwar länger, aber allein um das Bild vom Sensor abzuholen, braucht es schon 3 Sekunden, da fällt das auch nicht mehr groß auf. :stupid: (gäbe es eine API das Bild in Originalgröße abzurufen, dann würde das über 24 Sekunden dauern, mit 19200 BAUD :shock: und der Chip da drauf dreht und verarbeitet es in knapp 100ms und vergleicht es mit seiner ganzen Fingerdatenbank) [edit]
Delphi-Quellcode:
:duck:
// verständlicher
imFingerImage.Picture.Bitmap.PixelFormat := pf32bit; imFingerImage.Picture.Bitmap.SetSize(Width, Width); var B: PByte := @Bytes[0]; var C: PColor := imFingerImage.Picture.Bitmap.ScanLine[Width - 1]; for var i := Width * Width div 2 - 1 downto 0 do begin C^ := $00111111 * (B^ shr 4); Inc(C); C^ := $00111111 * (B^ and $0F); Inc(C); Inc(B); end; // bzw. for var i := Width * Width div 2 - 1 downto 0 do begin C^[i * 2] := $00111111 * (B[i] shr 4); C^[i * 2 + 1] := $00111111 * (B[i] and $0F); end; // holy shit imFingerImage.Picture.Bitmap.PixelFormat := pf32bit; imFingerImage.Picture.Bitmap.SetSize(Width, Width); var C: PIntegerArray := imFingerImage.Picture.Bitmap.ScanLine[Width - 1]; for var i := Width * Width - 1 downto 0 do C[i] := $00111111 * (Bytes[i div 2] shr (4 * Byte(not Odd(i))) and $0F); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:28 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