Entwickler-Ecke

Windows API - HBitmaps miteinander vergleichen


HenryHux - Fr 11.03.11 23:25
Titel: HBitmaps miteinander vergleichen
Hi, ich habe ja jetzt von in Thread TBitmaps auf HBitmaps gewechselt, oder zumindest versuche ich es.
Doch leider weiß ich von keiner Methode, die es mir ermöglicht, 2 HBitmaps auf Übereinstimmungen zu prüfen.
Bis jetzt ging das immer mit

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
Function TBasicFunctions.CompareImages(Bitmap1, Bitmap2 : TBitmap) : boolean;
begin
  If CompareMem (Bitmap1.Scanline[Bitmap1.Height - 1], Bitmap2.ScanLine [Bitmap2.Height - 1], Bitmap1.Width*Bitmap1.Height*SizeOf(TRGBTriple)) Then
    Result := true
  Else
    Result := false;
End;
.
Wie gesagt, nachdem ich die Nachteile von TBitmaps gesehen habe, wären mir HBitmaps lieber.
Hat da jemand eine Idee?

Lg


Moderiert von user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Sa 12.03.2011 um 00:50


jaenicke - Fr 11.03.11 23:30

Das hatte user profile icondelfiphan doch im anderen Thread schon geschrieben:
GetDIBits : http://msdn.microsoft.com/en-us/library/dd144879(v=vs.85).aspx


HenryHux - Sa 12.03.11 12:26

Ok, hatte ich übersehen.
Dennoch versteh ich das net ganz...
Erstmal muss man ein HDC als Parameter mitgeben. Also ist das Threadsafe?
Und auch ansonsten verstehe ich die Parameter nicht.
Ich muss ja folgendes herausbekommen :

Delphi-Quelltext
1:
CompareMem (Bitmap1.Scanline[Bitmap1.Height - 1], Bitmap2.ScanLine [Bitmap2.Height - 1], Bitmap1.Width*Bitmap1.Height*SizeOf(TRGBTriple))                    

Doch wie kriege ich die ganzen Werte aus dieser einen Funktion?

Lg


jaenicke - Sa 12.03.11 12:29

Dun übergibst wieviele und welche Zeilen du haben willst und den Buffer, in den diese kopiert werden sollen. Diesen Buffer wiederum kannst du dann normal vergleichen.


HenryHux - Sa 12.03.11 12:40

Ok, also auch mit CompareMem. Wie müssten denn die Parameter aussehen?
Bin bis jetzt soweit :
if CompareMem(GetDIBits(HDC, Bitmap1, 0, :D
Der nächste Parameter wäre die Anzahl der Scans. Doch ich kann ja nicht auf die Bildgröße zugreifen...
Bei den letzten 3 Parametern weiß ich auch nicht weiter, wobei der Letzte dann vlt eher DIB_RGB_COLORS wäre.

Der hier:
Zitat:
lpvBits [out]
A pointer to a buffer to receive the bitmap data. If this parameter is NULL, the function passes the dimensions and format of the bitmap to the BITMAPINFO structure pointed to by the lpbi parameter.

Weiß ich nicht, was für Pointer das sein sollten...

Und hier
Zitat:
lpbi [in, out]
A pointer to a BITMAPINFO structure that specifies the desired format for the DIB data.

Hab ich auch keinen Plan :D

Lg


jaenicke - Sa 12.03.11 12:52

user profile iconHenryHux hat folgendes geschrieben Zum zitierten Posting springen:
Weiß ich nicht, was für Pointer das sein sollten...
Pointer als Datentyp passt schon, du musst darin natürlich vorher auch Speicher reservieren.

Hier findest du ein Beispiel:
http://ksymeon.blogspot.com/2010/02/getdibits-vs-scanline-vs-pixels-in.html
Der Autor hat zwar keine Ahnung von Ergonomie, so dass man es kaum lesen kann, aber wenn du es aus der Seite herauskopierst, sollte es ja gehen. ;-)

Und es gibt noch viele andere Beispiele, wenn du einfach einmal bei Google nachfragst...


HenryHux - Sa 12.03.11 13:04

Habe schon viel auf Google gesucht, aber nicht das gefunden, was ich brauchte.
Auch die Webseite in deinem Post weicht ja davon recht weit ab, denn auch hier wird mit normalen TBitmaps gearbeitet.
Mein Problem ist ja eigentlich, dass ich zb. nicht an die Anzahl von den Scanlines komme, da ich dafür die Höhe eines Bitmaps bräuchte, wo ich aber bei einem HBitmap nicht dran komme (Betonung lag auf ich :D ).
Das mit den Pointern ist mir jetzt etwas klarer geworden..
Aber wie gesagt wie komme ich denn an die Höhe bzw an die Breite?

Lg


jaenicke - Sa 12.03.11 13:26

user profile iconHenryHux hat folgendes geschrieben Zum zitierten Posting springen:
Mein Problem ist ja eigentlich, dass ich zb. nicht an die Anzahl von den Scanlines komme, da ich dafür die Höhe eines Bitmaps bräuchte, wo ich aber bei einem HBitmap nicht dran komme (Betonung lag auf ich :D ).
Dann hast du die oben verlinkte Dokumentation nicht genau genug gelesen...
Zitat:
lpvBits [out]
A pointer to a buffer to receive the bitmap data. If this parameter is NULL, the function passes the dimensions and format of the bitmap to the BITMAPINFO structure pointed to by the lpbi parameter.


HenryHux - Sa 12.03.11 14:02

Nein...
Beim besten Willen, ich komm nicht drauf.
Denke mal du meinst sowas wie BITMAPINFO, aber auch das hilft mir nicht weiter, da ichs nicht hinbekomme :D
Keine Ahnung, wo ich noch ansetzen soll.
Hab auch ne Menge andere Sachen probiert wie GetObject, aber nichts will klappen -.-

Lg


jaenicke - Sa 12.03.11 14:11

Ungetestet, so ca. sollte es aussehen...

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
var
  BitmapInfo: TBitmapInfo;
  DataPointer: Pointer;
begin
  FillChar(BitmapInfo, SizeOf(BitmapInfo), 0);
  BitmapInfo.bmiHeader.biSize := SizeOf(BitmapInfo.bmiHeader);

  if GetDIBits(MyDC, MyBitmapHandle, 0, BitmapInfo.bmiHeader.biHeight,
    nil, BitmapInfo, DIB_RGB_COLORS) <> 0 then
  begin
    GetMem(DataPointer, BitmapInfo.bmiHeader.biHeight * BitmapInfo.bmiHeader.biWidth * 4);
    try
      if GetDIBits(MyDC, MyBitmapHandle, 0, BitmapInfo.bmiHeader.biHeight,
        DataPointer, BitmapInfo, DIB_RGB_COLORS) = BitmapInfo.bmiHeader.biHeight then
      begin
        ...
      end;
    finally
      FreeMem...
    end;
  end;


HenryHux - Sa 12.03.11 14:15

Jetzt hast du mir den Spaß verdorben... :D
Ne Spaß, danke ich probiers mal aus, muss dann aber noch ein paar Fragen stellen, damit ich auch verstehe was da abgeht =)

Lg


HenryHux - Sa 12.03.11 15:22

Ok, danke klappt so gut. =)
Noch ein paar Sachen geändert.
Doch was gebe ich am besten als HDC an?
Das Canvas.Handle eines TBitmaps wäre ja nicht mehr Threadsafe...

Lg


HenryHux - So 13.03.11 12:22

So, ich bin mit meinem vorherigen Problem jetzt einigermaßen durch, da kommt direkt das nächste -.-
Zitat:
hdc [in]
A handle to the device context.

heißt ich muss den DC für genau dieses Objekt angeben?
Wieso?
Wäre das nicht doppelt gemoppelt, wenn ich einmal den DC angebe und einmal das Handle?
Vor allem, was muss ich als HDC angeben?
Egal was ich angebe, es enstehen nur die Werte 0 und 1...
Also wie muss hier der HDC von dem jeweiligen HBitmap richtig erzeugt werden?

Lg