Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   C++ [GDI] Offscreen Bitmap - solved (https://www.delphipraxis.net/118164-%5Bgdi%5D-offscreen-bitmap-solved.html)

SnuffMaster23 1. Aug 2008 17:41


[GDI] Offscreen Bitmap - solved
 
Hoi
ich brauch mal wieder Hilfe.
Erstmal mein bisheriger Code:
Code:
  HBITMAP hBMP;
  HDC    hDC;
  RECT   Rect;
  int    *pixels = new int[512*512];

  hDC = CreateCompatibleDC(GetDC(NULL)); // GetDC(NULL) sollte einen DC zum Bildschirm zurückgeben, also in FARBE (bei mir jedenfalls)
  hBMP = CreateCompatibleBitmap(hDC, 512, 512);

  SelectObject(hDC, hBMP);

  Rect = (RECT){1, 1, 100, 100};
  SetDCBrushColor(hDC, 0x00000000);
  HBRUSH hBrush = CreateSolidBrush(0x000000FF);
  FillRect(hDC, &TextRect, hBrush);
  DeleteObject(hBrush);

  // zum angucken auf den Schirm blitten
  BitBlt(GetDC(NULL), 0, 0, 512, 512, hDC, 0, 0, SRCCOPY);

  DeleteObject(hBMP);
  DeleteDC(hDC);
  delete [] pixels;
Wie krieg ich jetzt nen DC/ein Bitmap mit ner bestimmten Farbtiefe (24, besser 32 Bit)? Der hier scheint jedenfalls monochrom zu sein, das rote Rechteck ist aus Schwarz und Weiß gerastert :(.
Und wie komm ich hinterher an die Pixeldaten? Bei CreateBitmap kann man ja nen Pointer angeben (pixels), den vermiss ich hier auch.

Wenns nur ein Rechteck zu zeichnen wär würd ichs ja selber machen, aber ich brauch GDI weil ich eigentlich Text zeichnen will.+

(Edith hats gelöst)

Medium 1. Aug 2008 18:17

Re: [GDI] Offscreen Bitmap
 
Was an TCanvas.TextOut() gefällt dir denn nicht?

Edit: Ach, C++! Wenns Borland C++ ist, gibts da aber ja auch die VCL und somit TCanvas 8)

SnuffMaster23 1. Aug 2008 19:12

Re: [GDI] Offscreen Bitmap
 
Mit dem [GDI] im Titel wollte ich eigentlich andeuten dass ich GDI benutzen will und keine VCL und kein TCanvas ;)

Das Problem ist auch garnicht der Text sondern wie oben steht einen bunten offscreen DC zu kriegen und hinterher an die Pixel zu kommen.

Medium 1. Aug 2008 19:50

Re: [GDI] Offscreen Bitmap
 
Zitat:

Zitat von SnuffMaster23
Wenns nur ein Rechteck zu zeichnen wär würd ichs ja selber machen, aber ich brauch GDI weil ich eigentlich Text zeichnen will.

Der Satz klingt erstmal wie: "Nagut, ich nehm gezwingenermaßen direkt die GDI direkt damit ich Text zeichnen kann", weniger wie: "Ich will bewusst auf die VCL verzichten, darum gehts" ;)

Zu dem Problem: Ich hab bisher sehr wenig mit der GDI direkt gemacht, aber hilft es evtl. den Brush mit SelectObject in den DC zu selektieren?

Ich weiss jetzt nicht, was GetDC(0) liefert, aber laut msdn kannst du CreateCompatibleDC direkt mit NULL aufrufen um einen Screen-DC zu erhalten. Vielleicht tuts das ja :)

SnuffMaster23 1. Aug 2008 20:04

Re: [GDI] Offscreen Bitmap
 
Zitat:

Zitat von Medium
Zitat:

Zitat von SnuffMaster23
Wenns nur ein Rechteck zu zeichnen wär würd ichs ja selber machen, aber ich brauch GDI weil ich eigentlich Text zeichnen will.

Der Satz klingt erstmal wie: "Nagut, ich nehm gezwingenermaßen direkt die GDI direkt damit ich Text zeichnen kann", weniger wie: "Ich will bewusst auf die VCL verzichten, darum gehts" ;)

Das sollte eigentlich klingen wie "Ein Rechteck kann ich mit zwei Schleifen selber ins Pixelarray zeichnen, Text nicht" :D
Es geht auch nicht darum auf die VCL zu verzichten, ich hab einfach garkeine. Gibt ja nicht nur Borland C++.


Zitat:

Zitat von Medium
Zu dem Problem: Ich hab bisher sehr wenig mit der GDI direkt gemacht, aber hilft es evtl. den Brush mit SelectObject in den DC zu selektieren?

Wenn ich auf einen Screen-DC zeichne isses rot. Außerdem nimmt FillRect ja extra einen Brush als Parameter, vom aktuell im DC selektierten steht auch nirgends was.


Zitat:

Zitat von Medium
Ich weiss jetzt nicht, was GetDC(0) liefert, aber laut msdn kannst du CreateCompatibleDC direkt mit NULL aufrufen um einen Screen-DC zu erhalten. Vielleicht tuts das ja :)

GetDC(NULL) liefert, wie im Kommentar steht einen Screen-DC, das hab ich nur zur Sicherheit da hingeschrieben. Davor hatte ich direkt NULL drin, macht aber keinen Unterschied.

Medium 1. Aug 2008 20:13

Re: [GDI] Offscreen Bitmap
 
MSDN-Library durchsuchenCreateCompatibleDC
Zitat:

A memory DC exists only in memory. When the memory DC is created, its display surface is exactly one monochrome pixel wide and one monochrome pixel high. Before an application can use a memory DC for drawing operations, it must select a bitmap of the correct width and height into the DC. To select a bitmap into a DC, use the CreateCompatibleBitmap function, specifying the height, width, and color organization required.
Das klingt exakt nach deinem Problem. Zudem:
Zitat:

Zitat von msdn zu CreateCompatibleBitmap()
The color format of the bitmap created by the CreateCompatibleBitmap function matches the color format of the device identified by the hdc parameter. This bitmap can be selected into any memory device context that is compatible with the original device.

D.h. irgendwie scheint dein DC vermurkst zu sein. Probier doch einfach mal mir zur Liebe nochmal statt "hDC = CreateCompatibleDC(GetDC(NULL));" "hDC = CreateCompatibleDC(NULL);", weil das wäre zumindest laut msdn der dokumentierte richtige Weg.

SnuffMaster23 1. Aug 2008 20:38

Re: [GDI] Offscreen Bitmap
 
Das klingt nach einem Teufelskreis, der DC ist monochrom und nimmt Farbinfos vom Bitmap, das Bitmap wird aber mit den Farben vom DC erzeugt. Und es gibt keine Mäglichkeit das zu ändern, jedenfalls hab ich noch keine gefunden :D

SetDIBits hab ich schon ausprobiert, allerdings ohne Erfolg. Damit hätte ich halt auf einmal die Farben gesetzt und mein Pixelarray eingeschleust.

So schauts aus, sowohl mit NULL als auch mit GetDC(NULL) bei CreateCompatibleDC
http://www.abload.de/img/guckctj.jpg

Medium 1. Aug 2008 23:04

Re: [GDI] Offscreen Bitmap
 
Also eines kann ich dir zumindest jetzt schon sagen: Es liegt nicht an einem Problem mit deinem Rechner. Ich hab deinen Code mal (mangels C++ Compiler) nach Delphi übersetzt, und bekomme das selbe Resultat. Immerhin schon mal etwas ;)


Edit:
Folgendes klappt:
DC := GetDC(0);
oder
DC := CreateDC(PChar('DISPLAY'), nil, nil, nil);

Beides gibt einen DC zurück, auf den sich farbig zeichnen lässt. Sobald man aber CreateCompatibleDC() über einen derjenigen ausführt, ist der resultierende wieder monochrom. Daher sollte an und für sich auf jeden Fall die 2. Variante benutzbar sein.

Ich habe mir das auch grad nur zusammengedokort da ich "zu Fuß" über GDI bislang auch nur eher sporadisch unterwegs war, aber hey! Zumindest war das Rechteck rot ;)

helgew 2. Aug 2008 00:40

Re: [GDI] Offscreen Bitmap
 
Willst du nicht erst einmal ein Bitmap erzeugen?
http://msdn.microsoft.com/en-us/library/ms532305.aspx

Danach kannst du dann von DC zu DC blitten, wie du lustig bist :)

Medium 2. Aug 2008 00:49

Re: [GDI] Offscreen Bitmap
 
Hat er ;)
Zitat:

Zitat von SnuffMaster23
Code:
  hBMP = CreateCompatibleBitmap(hDC, 512, 512);


SnuffMaster23 2. Aug 2008 01:28

Re: [GDI] Offscreen Bitmap
 
Ja aber wenn ich aufn monochromen DC blit hab ich auch nix davon.
Lustig bin ich fast immer, daran sollts net scheitern :D

Der kompatible DC is erstmal immer monochrom und 1x1 Pixel groß. Der braucht ja dann ein (buntes) größeres Bitmap. Aber es geht halt auch nur mit nem kompatiblen Bitmap, wenn ich eins mit CreateBitmap erzeug kann des noch so bunt sein, er malt mir dann aufn Bildschirm, selbst mit dem Memory DC :(

Medium 2. Aug 2008 01:49

Re: [GDI] Offscreen Bitmap
 
Nochmal in Klartext: Ersetze diese Zeile:
Code:
hDC = CreateCompatibleDC(GetDC(NULL));
mit dieser:
Code:
hDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
Sonst nichts, und schau ob das so ist, wie du es möchtest.

SnuffMaster23 2. Aug 2008 13:51

Re: [GDI] Offscreen Bitmap
 
Nein, so hatt ichs zuerst. Das malt zwar in Farbe aber aufn Bildschirm und nicht ins Bitmap :(
Sowohl mit nem kompatiblen als auch mit nem 'normalen' Bitmap.

Medium 2. Aug 2008 13:58

Re: [GDI] Offscreen Bitmap
 
Hm, okay, mist :) Dann muss ich hier leider aussteigen, das war schon leicht über der Grenze meines Lateins ;)

Ich sollte mich eindeutig mal mehr mit der API beschäftige...

SnuffMaster23 2. Aug 2008 16:12

Re: [GDI] Offscreen Bitmap
 
Ok, ich hab einen kleinen Fortschritt erzielt^^
Ich komm an meine Pixeldaten :love:
Code:
  GetDIBits(hDC, hBMP, 0, 512, pixels, &BmpInfo, DIB_RGB_COLORS);
Fehlt nur noch etwas Farbe...

//Edit:
Manchmal hilfts in Beispiele zu gucken die nicht ganz direkt was damit zu tun haben: Capturing an Image
Zitat:

Code:
hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL);
hdcCompatible = CreateCompatibleDC(hdcScreen);
 
// Create a compatible bitmap for hdcScreen.
 
hbmScreen = CreateCompatibleBitmap(hdcScreen,
                     GetDeviceCaps(hdcScreen, HORZRES),
                     GetDeviceCaps(hdcScreen, VERTRES));

Die erzeugen einen bunten DC, dazu einen Memory DC und ein Bitmap zum bunten DC, nicht zum Memory DC der ja auch bunt sein sollte :D

Das hier tuts auch und ist meiner Meinung nach sauberer weil kein ungenutzter DC erzeugt werden muss:
Code:
  HDC       hDC,
             hTmpDC = GetDC(HWND_DESKTOP);
// ...
  hDC = CreateCompatibleDC(hTmpDC);
  hBMP = CreateCompatibleBitmap(hTmpDC, 512, 512);

helgew 2. Aug 2008 17:52

Re: [GDI] Offscreen Bitmap - solved
 
@Medium ops... passiert *g* das nächste mal bin ich wohl lieber ruhig ;)

Medium 2. Aug 2008 18:46

Re: [GDI] Offscreen Bitmap - solved
 
Also das Bitmap mit dem ersten DC als Parameter erstellen, um es dann im davon ausgehend erzeugten zweiten DC zu benutzen ist die Lösung. Machmal... also, nur manchmal, da wundere ich mich schon ob jetzt der Entwickler dieser API einen im Tee hatte, oder ob mein Kaffee nur zu schwach war um dem einen tieferen Sinn beimessen zu können :gruebel:


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:22 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