AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

CreateBitmap

Ein Thema von Thunderman · begonnen am 18. Jan 2005 · letzter Beitrag vom 19. Jan 2005
Antwort Antwort
Thunderman

Registriert seit: 14. Jun 2002
Ort: Lüneburg
13 Beiträge
 
#1

CreateBitmap

  Alt 18. Jan 2005, 17:53
Hallo!

Nach langer Zeit bin ich mal wieder an Pascal dran und schon hapert es an der Darstellung einer Grafik. Wenn ich LoadImage() verwende um mein HBITMAP zu erzeugen funktioniert es ja bereits. Doch aus verschiedenen Gründen möchte ich es mit CreateBitmap() erzeugen. Ich habe bereits die Daten des Bitmap hintereinander in den Speicher gelesen, auf den der Pointer s_Image.Data zeigt. Der folgende Code gibt auch ein Handle ungleich 0 zurück. Der Aufruf sollte also erfolgreich gewesen sein:
s_Bitmap := CreateBitmap(s_Image.Width, s_Image.Height, s_Image.Planes, s_Image.Bits, s_Image.Data); Doch mit dem folgenden Code, der zur Darstellung des mit LoadImage geladenen Bitmaps funktionierte, kann ich es nicht ins Fenster zeichnen:
Delphi-Quellcode:
  s_h_DC := GetDC(s_h_Wnd);
  s_hdc_mem := CreateCompatibleDC(s_h_DC);
  s_temp := SelectObject(s_hdc_mem, s_Bitmap);
  BitBlt(s_h_DC, 0, 0, 480, 320, s_hdc_mem, 0, 0, SRCCOPY);
s_h_Wnd ist das Handle meines Fensters. Ich hoffe hier findet jemand meinen Fehler.
Thunderman
Bei schwierigen Problemen entscheiden wir uns einfach für die richtige Lösung. Klar?
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: CreateBitmap

  Alt 18. Jan 2005, 18:40
Moin,

kann es eventuell daran liegen, dass das Bitmap nicht geräteunabhängig ist.

  Bitmap.HandleType:=bmDIB; MfG
Thorsten
  Mit Zitat antworten Zitat
Thunderman

Registriert seit: 14. Jun 2002
Ort: Lüneburg
13 Beiträge
 
#3

Re: CreateBitmap

  Alt 18. Jan 2005, 19:45
s_Bitmap ist eben nur ein Handle und zeigt auf ein geräteabhängiges Bitmap. Daher verwende ich ja auch CreateCompatibleDC() bzw. SelectObject(). Bitmap.HandleTyp kann ich übrigens nirgends aufrufen, da ich kein TBitmap verwende. Ich habe nur die Pixel im RGB-Format in einem Speicherbereich und möchte diese nun auf einem Fenster ausgeben.
Thunderman
Bei schwierigen Problemen entscheiden wir uns einfach für die richtige Lösung. Klar?
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: CreateBitmap

  Alt 18. Jan 2005, 20:37
Moin,

da man nicht viel von deinem Code sehen kann...

Habe ich mal folgendes probiert...

Delphi-Quellcode:
procedure malen;
var bmp:HBITMAP;
    _HDC, hDC: windows.HDC;
begin
  _HDC := GetDC(Self.Handle);
  hDC := CreateCompatibleDC(_HDC);
  bmp := CreateBitmap(100,100,1,GetDeviceCaps(hDC, BITSPIXEL),nil);
  SelectObject(hDC, bmp);

  BitBlt(hDC, 0, 0, 480, 320, image1.Canvas.Handle, 0, 0, cmSrcCopy); // Nur zum Füllen von bmp

  BitBlt(_HDC, 0, 0, 480, 320, hDC, 0, 0, cmSrcCopy);
end;
das funktioniert.

Als Beispiel habe ich ein Image, dessen Inhalt ich nur über den Handle auf die Form male.

MfG
Thorsten
  Mit Zitat antworten Zitat
Thunderman

Registriert seit: 14. Jun 2002
Ort: Lüneburg
13 Beiträge
 
#5

Re: CreateBitmap

  Alt 19. Jan 2005, 11:57
Hallo!

Das ist ja eigentlich genau das, was ich mache. Und wenn ich das Bitmap mit LoadImage() lade funktioniert es auch. Nur wenn ich das Bitmap mit CreateBitmap selbst erzeuge geht es nicht. Ich habe nur leider kein TImage wie bei deinem Beispiel, sondern nur die Bilddaten roh im Speicher. Der Aufruf von CreateBitmap() damit funktioniert auch, aber er zeigt trotzdem kein Bild an. Also muss denke ich noch irgendtwas falsch sein. Hier jetzt das ganze als etwas besserer Beispielcode zum einfachereren nachvollziehen:
Delphi-Quellcode:
procedure Test(Bilddaten: Pointer; Breite, Hoehe, Planes, Bits: Integer);
var
  win_hdc : HDC;
  mem_hdc : HDC;
  bmp : HBITMAP;
begin
  bmp := CreateBitmap(Breite, Hoehe, Planes, Bits, Bilddaten); // Bitmap aus den Rohdaten erzeugen
  if bmp = 0 then
  begin
    ShowMessage('Fehler');
    Exit;
  end;
  win_hdc := GetDC(win_hWnd); // DC des Fensters
  mem_hdc := CreateCompatibleDC(win_hdc); // einen dazu kompatiblen DC im Speicher erzeugen
  SelectObject(mem_hdc, bmp); // das Bitmap in diesen DC wählen
  BitBlt(win_hdc, 0, 0, Breite, Hoehe, mem_hdc, 0, 0, SRCCOPY);
end;
Wenn man CreateBitmap() hier durch LoadImage(hInstance,'irgendeinbild.bmp',IMAGE_BITMAP,480,320,LR_LOADFROMFILE) ersetzt funktioniert das ganze.
Die Bilddaten lade ich mit einem TFileStream, was auch in einer anderen Anwendung wo ich sie mit OpenGL darstelle funktioniert.
Thunderman
Bei schwierigen Problemen entscheiden wir uns einfach für die richtige Lösung. Klar?
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: CreateBitmap

  Alt 19. Jan 2005, 18:22
Moin,

da kann ich dir leider nicht weiterhelfen. Würde ich ja gern, aber ich kann keine Gedanken lesen. ich habe keine Ahnung was du da machst. Dein Hinweis mit dem TFileStream ist ja sehr nett, ich weiss allerdings nicht wie bzw. was du da genau machst.

Sorry
Thorsten
  Mit Zitat antworten Zitat
Thunderman

Registriert seit: 14. Jun 2002
Ort: Lüneburg
13 Beiträge
 
#7

Re: CreateBitmap

  Alt 19. Jan 2005, 18:31
Das ist auch nicht sonderlich wichtig, denn wie gesagt enthält Bilddaten nur sämtliche RGB-Werte der Pixel des Bildes hintereinanderweg. Im Grunde ist dafür folgender Code zuständig:
Delphi-Quellcode:
GetMem(Result.Data, InfoHeader.biSizeImage);
S.ReadBuffer(Result.Data^, InfoHeader.biSizeImage);
InfoHeader enthält die wichtigen Informationen aus der *.bmp Datei wie Farbtiefe, Breite und Höhe und eben Bildgröße. Result.Data verwende ich anschließend eben als Bilddaten in der oben genannten Funktion.
Thunderman
Bei schwierigen Problemen entscheiden wir uns einfach für die richtige Lösung. Klar?
  Mit Zitat antworten Zitat
omata

Registriert seit: 26. Aug 2004
Ort: Nebel auf Amrum
3.154 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: CreateBitmap

  Alt 19. Jan 2005, 20:42
Gut, ich hatte ein bißchen experimentiert und bekomme etwas gezeichnet. Allerdings sieht das nicht so aus wie mein Bild, weil ich dein kompischen Konzept nicht nachvollziehen kann. Aber vielleicht hilft es dir, weil du die Parameter für CreateBitmap besser kennst...

Delphi-Quellcode:
var Datei:TFileStream;
    Buffer:Pointer;
    bmp:HBITMAP;
    _hDC, hDC:windows.hDC;
    nWidth, nHeight:integer;
begin
  Datei:=TFileStream.Create('Bild.bmp', 0);
  try
    GetMem(Buffer, Datei.Size);
    Datei.ReadBuffer(Buffer^, Datei.size);
    _hDC := GetDC(Self.Handle);
    hDC := CreateCompatibleDC(_hDC);
    bmp := CreateBitmap(100, 100, 1, GetDeviceCaps(hDC, BITSPIXEL), Buffer);
    SelectObject(hDC, bmp);
    BitBlt(_hDC, 0, 0, 100, 100, hDC, 0, 0, cmSrcCopy);
    FreeMem(Buffer, datei.Size);
  finally
    Datei.free;
  end;
end;
MfG
Thorsten
  Mit Zitat antworten Zitat
Thunderman

Registriert seit: 14. Jun 2002
Ort: Lüneburg
13 Beiträge
 
#9

Re: CreateBitmap

  Alt 19. Jan 2005, 22:44
Danke schonmal.
Es liegt scheinbar an den Bits bei CreateBitmap() und dem CompatibleDC. Das du nur was komisches siehst liegt auch daran, dass die Ladefunktion des Bitmaps nicht nur aus dem ReadBuffer() besteht, sondern man noch RGB Werte vertauschen muss, etc. Ich versuch nochmal herauszufinden, wie sich die Bits, etc unterscheiden und warum es daher vorher nicht klappte.
Thunderman
Bei schwierigen Problemen entscheiden wir uns einfach für die richtige Lösung. Klar?
  Mit Zitat antworten Zitat
Thunderman

Registriert seit: 14. Jun 2002
Ort: Lüneburg
13 Beiträge
 
#10

Re: CreateBitmap

  Alt 19. Jan 2005, 23:47
So,

hier nun die letzten Hinweise, falls mal jemand etwas ähnliches versucht:

-achtet darauf welche Farbtiefe das Device des Fensters hat. In meinem Fall 32bit - das Bitmap war aber nur 24bit.
-Bitmaps in *.bmp Dateien sind (zumindest in meinen Fällen) von hinten nach vorne und von unten nach oben gespeichert.

In meinem konkreten Fall musste ich also die Bilddaten bearbeiten. Zum einen für jeden Pixel einen Alphawert (32bit) hinzufügen und außerdem die Pixeldaten umsortieren. Diese Funktion muss ich demnächst noch optimieren, aber für das erste tut sie es nun und ich kann mich wichtigerem widmen. Danke. Warum ich nicht direkt an die Farbtiefe dachte weiß ich nicht, jedenfalls funktioniert es jetzt. Gibt es eigentlich eine Möglichkeit Bitmaps mit BitBlt() anzuzeigen, die nicht der Farbtiefe des Devices entsprechen? Ich möchte nämlich nur ungern immer meine Bitmaps entweder auf 32bit hoch oder auf 24bit runterrechnen. Oder kann man davon ausgehen, dass heutzutage jedes Device unter Windows 32bit ist? Ich befürchte eher nicht, 16bit könnte es ja auch noch geben...
Thunderman
Bei schwierigen Problemen entscheiden wir uns einfach für die richtige Lösung. Klar?
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:13 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz