![]() |
BMP ohne TBITMAP anzeigen
Ich bin dabei, ein schon etwas älteres Programm, das in Assembler vorliegt, in Delphi umzusetzen. Das Programm stammt aus der CGA-Zeit, als es toll war, 4 Farben zur Verfügung zu haben: 0=Schwarz, 1=Cyan, 2=Magenta,3=Weiß. 1 Byte enthielt 4 Pixel zu je 2 Bit. Ich benutze jetzt eine BMP mit 256 Farben, wobei von denen nur die ersten 4 verwendet werden, als Farben 0,1,2,3 mit den o.g. Farbwerten in der Color-Tabelle.
Ich erstelle auf diese Weise aus den Pixel-Mustern des Ausgangsprogrammes intern eine BMP für die ich folgenden RECORD angelegt habe
Code:
Wenn ich eine derart erzeugt BMP als Datei ausgebe, entsteht genau die gewünschte Datei :
Type
TPixelArr = Array[1..200,1..320] of Byte; ThkBMP = RECORD // Länge = 65.078 Bytes bmf : TBitMapFileHeader; // 14 Bytes + 0 bmi : TBitMapInfoHeader; // 40 Bytes + 14 bmiColors : Array[0..255] of RGBQUAD; // 1024 Bytes + 54 Rot, Grün, Blau, Res FARB-PALLETTE bmPixelArr : TPixelArr; // 64000 Bytes + 1078 Pixel End; // ThkBMP = RECORD // +65078 ---- Ende = Länge der BMP ----- Var hkBMP : ThkBMP; lpAnfBmpPic : ^TtagBitmapInfo; lpPuBmpPIC : ^TPixelArr; ![]() Vor einiger Zeit habe ich mal ein C++ Programm geschrieben und dort Bilddateien derart angezeigt, dass sie immer in das zugehörige Fenster passen. Der betreffende Code sieht folgendermaßen aus:
Code:
Ich möchte in dem Delphi-Programm die einzelnen Spiel-Teile mit den vorhandenen AND/OR-Masken realisieren, dazu dürfen die Farben aber nur 0..3 sein. Wenn ich die BMP in eine TBITMAP bringe, stimmen die Farben nicht mehr, ich kann die Pixel nicht verändern (in meinem RECORD kann ich das problemlos machen), TBITMAP kann ich nicht nutzen. Das kleine 320x200 Bild möchte ich jeweils um den Faktor 3 in ein 960x600 Bild vergrößert anzeigen, das kann StretchDIBits sehr gut und schnell machen.
// ============< (messagePIC) von WndProcPIC >=====================
case WM_PAINT: // Fenster neu aufbauen // ================================================================ SetCursor(LoadCursor(NULL, IDC_WAIT)); hdcPIC = BeginPaint (hwndPIC, &psPIC) ; //-------------------------- // PIC-Datei anzeigen //-------------------------- lpAnfBmpPic = HoleAnfBmpPic (lpPuBmpPIC) ; // Anfang der Bild-Daten in BMP-Puffer SetStretchBltMode (hdcPIC, STRETCH_HALFTONE) ; // Streckmodus // ------------------------------------------------------------------------ // Fensteroptimal // ------------------------------------------------------------------------ fFaktorX = (float) wXmaxFePIC / (float) wBmpBreite ; fFaktorY = (float) wYmaxFePIC / (float) wBmpHoehe; if ( fFaktorX < fFaktorY ) { wFenBreiX = (WORD) (fFaktorX * (float) wBmpBreite) -10 ; wFenHoehY = (WORD) (fFaktorX * (float) wBmpHoehe ) ; } else { wFenBreiX = (WORD) (fFaktorY * (float) wBmpBreite) ; wFenHoehY = (WORD) (fFaktorY * (float) wBmpHoehe ) -10 ; } wFenLiObX = (wXmaxFePIC - wFenBreiX ) >> 1 ; wFenLiObY = (wYmaxFePIC - wFenHoehY ) >> 1 ; StretchDIBits ( hdcPIC, // DIB-Quelle in ZIEL-Fenster angepaßt wFenLiObX, // X-Ursprung-Fenster wFenLiObY, // Y-Ursprung-Fenster wFenBreiX, // Fenster-Breite wFenHoehY, // Fenster-Höhe 0, // X-Ursprung-BMP 0, // Y-Ursprung-BMP wBmpBreite, // X-Breite BMP wBmpHoehe, // Y-Höhe BMP (LPSTR) lpAnfBmpPic, // Anf Bild-Daten in BMP-Pu (LPBITMAPINFO) lpPuBmpPIC, // BITMAPINFOHEADER DIB_RGB_COLORS, // Die Farb-Tab enthält RGB-Werte SRCCOPY ) ; // Operation: Quelle => Ziel kopieren EndPaint (hwndPIC, &psPIC) ; SetCursor (LoadCursor (NULL, IDC_ARROW)) ; // Pfeil-Cursor return 0 ; Mein BMP-RECORD ist genau so aufgebaut, wie in dem C++ Programm. Er ist voll identisch mit der BMP-Datei. Wenn ich unter Delphi 7 die BMP aus dem RECORD mit Hilfe von StretchDIBits anzeigen will, dann bekomme ich immer Umwandlungsfehlermeldungen. Dazu benötige ich eine fachkundige Hilfe.
Code:
[Fehler] Soko1u.pas(301): Die Typen der tatsächlichen und formalen Var-Parameter müssen übereinstimmen
lpAnfBmpPic := @(hkBMP.bmi);
lpPuBmpPIC := @(hkBMP.bmPixelArr); StretchDIBits ( Form1.Handle, // DIB-Quelle in ZIEL-Fenster angepaßt 10, // X-Ursprung-Fenster 10, // Y-Ursprung-Fenster 960, // Fenster-Breite 600, // Fenster-Höhe 0, // X-Ursprung-BMP 0, // Y-Ursprung-BMP 320, // X-Breite BMP 200, // Y-Höhe BMP lpAnfBmpPic, // Anf Bild-Daten in hkBMP+1078 lpPuBmpPIC, // BitMapInfoHeader <== Hier wird der Fehler angezeigt DIB_RGB_COLORS, // Die Farb-Tab enthält RGB-Werte SRCCOPY ) ; // Operation: Quelle => Ziel kopieren |
AW: BMP ohne TBITMAP anzeigen
tja ein Window Handle ist nun mal nicht gleich HDC (handle zum Destination Device Context).
Siehe Form1.Handle Sollte wohl Form1.Canvas.Handle sein. (oder über API = GetDC(Form1.Handle)) Es steht doch dahinter.. Zitat:
Du kannst für den Typ BITMAPINFO keinen Pointer auf ein PixelArray übergeben. Wenn dann "@bmi" vorrausgesetzt bmi ist als tagBITMAPINFO definiert. gruss |
AW: BMP ohne TBITMAP anzeigen
Danke für die Antwort.
Bei den Zuweisungen der beiden Pointer habe ich offenbar etwas verwechselt. Ich habe es nun ausgetauscht, weiterhin kommt der Umwandlungsfehler. Jetzt sieht es so aus
Code:
lpAnfBmpPic := @(hkBMP.bmPixelArr);
lpPuBmpPIC := @(hkBMP.bmi); {} StretchDIBits ( Form1.Canvas.Handle, // DIB-Quelle in ZIEL-Fenster angepaßt 10, // X-Ursprung-Fenster 10, // Y-Ursprung-Fenster 960, // Fenster-Breite 600, // Fenster-Höhe 0, // X-Ursprung-BMP 0, // Y-Ursprung-BMP 320, // X-Breite BMP 200, // Y-Höhe BMP lpAnfBmpPic, // Anf Bild-Daten in hkBMP+1078 lpPuBmpPIC, // BitMapInfoHeader DIB_RGB_COLORS, // Die Farb-Tab enthält RGB-Werte SRCCOPY ) ; // Operation: Quelle => Ziel kopieren
Code:
tagBITMAPINFO habe ich bewusst nicht benutzt, weil durch das darin enthaltene bmiColors-Array der Record um 4 Bytes zu lang war.
tagBITMAPINFO = packed record
bmiHeader: TBitmapInfoHeader; bmiColors: array[0..0] of TRGBQuad; end; Ein Zeiger auf TBitMapInfoHeader ist adressmäßig identisch mit einem Zeiger auf tagBitMapInfo. In meinem Record kommen nach dem BitmapInfoHeader ja sofort die Colors für 256 Farben. |
AW: BMP ohne TBITMAP anzeigen
Zitat:
Delphi-Quellcode:
lpPuBmpPIC : ^TPixelArr;
geändert hast. Zitat:
Delphi-Quellcode:
bmi : TBitMapInfoHeader; // 40 Bytes + 14
![]() gruss |
AW: BMP ohne TBITMAP anzeigen
Nochmals DANKE.
Ich habe alles nochmal durchgesehen und die Verwechselungen beseitigt. Jetzt funktioniert es. Hier noch einmal der berichtigte Code. ich habe nach dem tagBitmapInfo nur noch die Colors 1..255 definiert, weil [0,0] bereits in tagBitmapInfo enthalten ist.
Code:
Die Pointer-Variablen habe ich weggelassen und stattdessen die Angaben direkt eingetragen
TPixelArr = Array[1..200,1..320] of Byte;
ThkBMP = RECORD // Länge = 65.078 Bytes bmf : TBitMapFileHeader; // 14 Bytes + 0 bminfo : tagBitmapInfo; // 44 Bytes + 14 bmiColors2 : Array[1..255] of RGBQUAD; // 1020 Bytes + 58 Rot, Grüm, Blau FARB-PALLETTE bmPixelArr : TPixelArr; // 64000 Bytes + 1078 Pixel End; // ThkBMP = RECORD // +65078 ---- Ende der BMP ----- Var hkBMP : ThkBMP;
Code:
Ich hoffe, ich darf noch eine Zusatzfrage stellen...
StretchDIBits ( Form1.Canvas.Handle, // DIB-Quelle in ZIEL-Fenster angepaßt
10, // X-Ursprung-Fenster 10, // Y-Ursprung-Fenster 960, // Fenster-Breite 600, // Fenster-Höhe 0, // X-Ursprung-BMP 0, // Y-Ursprung-BMP 320, // X-Breite BMP 200, // Y-Höhe BMP @(hkBMP.bmPixelArr), // Anf Bild-Daten in hkBMP+1078 hkBMP.bminfo, // tagBitMapInfo DIB_RGB_COLORS, // Die Farb-Tab enthält RGB-Werte SRCCOPY ) ; // Operation: Quelle => Ziel kopieren Gibt es eine Möglichkeit, Farbcodes direkt in Bmp.Canvas.Pixels einzutragen, wenn man statt einem RECORD, wie ich es gemacht habe, TBITMAP verwendet und kann man auch auf die Einträge in der Colortabelle Einfluss nehmen ? Ich habe das versucht, es gibt keinen Fehler, aber in der erzeugten BMP stehen nicht die von mir gewünschten Farbeinträge, sondern nahezu alles ist 0.
Code:
Procedure MakeBMP2;
Var Bmp : TBitmap; yZei, xSpa, i : Integer; by : Byte; H : HPalette; P : PLogPalette; Begin Bmp := TBitmap.Create; Bmp.Width := 320; Bmp.Height := 200; Bmp.PixelFormat := pf8bit; GetMem(P, SizeOf(TLogPalette) + (SizeOf(TPaletteEntry) * 255)); P.palVersion := $300; P.palNumEntries := 256; for i := 0 to 255 do Begin P.palPalEntry[i].peFlags := 0; Case i of 0: Begin P.palPalEntry[i].peBlue := $00; // 0 = Schwarz P.palPalEntry[i].peGreen := $00; P.palPalEntry[i].peRed := $00; End; 1: Begin P.palPalEntry[i].peBlue := $FF; // 1 = CYAN P.palPalEntry[i].peGreen := $FF; P.palPalEntry[i].peRed := $00; End; 2: Begin P.palPalEntry[i].peBlue := $FF; // 2 = Magenta P.palPalEntry[i].peGreen := $00; P.palPalEntry[i].peRed := $FF; End; 3: Begin P.palPalEntry[i].peBlue := $FF; // 3 = Weiss P.palPalEntry[i].peGreen := $FF; P.palPalEntry[i].peRed := $FF; End; else Begin P.palPalEntry[i].peRed := 0; P.palPalEntry[i].peGreen := 0; P.palPalEntry[i].peBlue := 0; End; End; // Case End; H := CreatePalette(P^); if H <> 0 then Bmp.Palette := H; for yZei := 1 to 200 do Begin for xSpa := 1 to 320 do Begin by := ELEVBINarr[yZei,xSpa]; Bmp.Canvas.Pixels[xSpa-1,yZei-1] := by; End; // for xSpa End; // for yZei Bmp.SaveToFile(DsnBMP2); FreeMem(P); End; |
AW: BMP ohne TBITMAP anzeigen
lade dir mal mein
![]() Dort findest du eine Unit Palette.. Verfolge einfach mal wie die Palette initialisiert wird. Danach sollten deine Fragen eigentlich beantwortet sein. Nebenbei! Für neue Fragen sind neue Threads allemal besser als zusätzliche Fragen anzuhängen.. Meistens liest das dann keiner mehr. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:11 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