Autor |
Beitrag |
Aya
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: So 06.10.02 04:54
Hi,
es gibt ja die Funktion ScanLine vom TBitmap... nun wollte ich mal fragen ob mir jemand sagen kann was genau die funktion macht, denn ich würde die auch gerne für dinge benutzen die nichts mit einem Bitmap zu tun haben (z.B. um direkt auf nen Canvas zu zeichnen).
Wäre super wenn mir da jemand weiterhelfen kann (hab die PDSK mal durchsucht aber nur SetPixel() gefunden, und das ist genausolahm wie das Canvas.Pixels[]..  )
Au'revoir,
Aya
|
|
Addy
      
Beiträge: 43
|
Verfasst: So 06.10.02 10:37
Die Eigenschaft ScanLine liefert dir die Adresse des ersten Pixels der angegebenen Pixelzeile. Auf diese Weise kannst du einzelne Pixel direkt im Speicher setzen (Eigenschaft PixelFormat beachten!).
Mit einem TCanvas-Objekt kannst du das logischerweise nicht machen, da ein Canvas keinen eigenen Speicher besitzt, sondern nur einen Bereich auf dem Bildschirm repräsentiert. Du kannst jedoch auf einem Bitmap zeichnen und dieses auf das Canvas kopieren.
|
|
Aya 
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: So 06.10.02 14:54
Hi,
aber mal so ganz theoretisch...
Wenn ich ein Bitmap 640x480 auf ein Canvas kopiere, dann macht Windows Intern ja eigentlich nichts anderes als das Bitmap pixel für pixel auf das Canvas zu zeichnen... und das mit z.B. CopyRect geht auch wahnsinnig schnell...
Also muß (!) da doch eine schnellere methode sein..?
Au'revoir,
Aya
|
|
Addy
      
Beiträge: 43
|
Verfasst: So 06.10.02 19:25
Also, verstehe ich das richtig: Du willst auf irgendeinem TCanvas-Objekt einzelne Pixel setzen, dies aber nicht mit Hilfe von SetPixel tun (da dies zu langsam ist), sondern auf den Speicher direkt zugreifen.
Das geht aber nicht mit DCs (TCanvas), sondern nur mit Bitmaps. Da hilft nur Kopieren 
|
|
Aya 
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: Mo 07.10.02 04:56
Hi,
also... ja, schon...
Aber mein "problem" ist einfach, das mir selbst die ScanLine zu langsam ist... *gg*
Ich hab in dem GrafikProgramm an dem ich Arbeite unter anderem auch eine LayerFunktion drin, bei 2 Layern (640x480) ist das ja noch einigermaßen schnell... aber bei 3 oder mehr..?? nee... lahm ohne ende
und es gibt ja diese TImage32 Komponente, bei der geht es ja wahnsinnig schnell (in der LayerDemo davon zummindest)... also muß es ja irgendeine schnellere methode für soetwas geben!!
Und, um eins vorweg zu nehmen.. ich nehme nicht das TImage32 *g* Wie ich oft sagte bin ich FremdKompo Gegnerin... auch wenn's oft probleme macht, bisher hab ich noch alles gelöst bekommen
Au'revoir,
Aya
|
|
Addy
      
Beiträge: 43
|
Verfasst: Mo 07.10.02 17:33
Dann probier mal die API-Funktion SetDIBits, eventuell ist die schneller.
|
|
Matthias
      
Beiträge: 121
|
Verfasst: Mo 07.10.02 17:57
Hallo Aya,
soweit ich weiss, werden wenn es um die extrem schnelle Verarbeitung von Bitmaps geht, DIB's verwendet. Demos, die ich hier gesehen hab verblüffen mich immer wieder, wie schnell Windows sein kann.
Da ich mich selbst auch viel mit der Analyse von Grafiken beschäftige, bin ich seit längerem am überlegen, ob ich umsteige. Zur Zeit verwende ich auch Bitmaps und Scanline.
Nähere Informationen findest Du unter www.droopyeyes.com/ bzw. www.delphi-jedi.org.
Übrigens bin ich auch Gegner von Fremd Kompos, es sei denn es wird der Source mitgeliefert. In diesem Fall bin ich gerne bereit auch etwas zu investieren, da da meine Arbeitszeit zur Erstellung dieser Tools meist deutlich mehr kostet, als vorhandene zu verwenden und eventuell anzupassen.
ciao
Matthias
|
|
Aya 
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: Mo 07.10.02 18:18
Hi,
kann mir mal jemand nen Beispiel zu dem SetDIBits geben??
Weil, so ganz verstehen tu ich da auf anhieb nich welche Parameter der alles will... *g*
Au'revoir,
Aya
|
|
Matthias
      
Beiträge: 121
|
Verfasst: Di 08.10.02 00:12
Hy,
ich weiss nicht genau, ob Du das erreichen willst aber SetDiBits kopiert eine DIB in eine DDB.
Aber zunächst einmal ein bischen Theorie. Eine DIB ist eine Bitmap in einem bestimmten Format im globalen Speicher. Auf diese Bitmap besitzt Du also ein Handle.
Das Handle auf diesen Speicher ist in meinem Bsp. HBmp
Zunächst einmal die Variablen:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
| var Dib :PBitmapInfoHeader; // Zeiger auf den Info Header des DIB // oder auch der Start der DIB Bits :PByte; // Zeiger auf die Pixel des DIB ColorTableSize:longint; // Grösse der Farbpalette Bitmap :HBitmap; // Handle der Ergebnis Bitmap (DDB) DC :HDC; // Device Context
// generiere eine Zeiger auf den Info Header der DIB Dib:=PBitmapInfoHeader(GlobalLock(hDib));
// jetzte könnte ich erstmal Prüfen, ob der Zeiger NIL hab jetzt aber // keine Lust dazu
// Bereche die größe der Farbpalette ColorTableSize:=longint((DibNumColors(Dib)*sizeof(TRGBQuad))); // Generiere einen Zeiger auf das Array mit dem eigentlichen // Inhalt (Pixel) der DIB Bits:=addr(PBitmapInfo(Dib)^.BmiColors); Bits:=pointer(longint(bits)+ColorTableSize);
// Devicecontext für das aktuelle Fenster holen // Handle ist ein Fenster Handle (Typ HWND) DC:=GetDC(Handle);
// DIB in eine DDB kopieren // Außerdem gehe ich hier von einer Schwarzweissbitmap aus BitMap:=CreateBitmap(dib^.biWidth,dib^.biHeight,1,1,nil); SetDIBits(DC,BitMap,0,dib^.biHeight,PChar(Bits),PBitmapInfo(Dib)^,DIB_RGB_COLORS);
// Devicecontect wieder freigeben ReleaseDC(Handle,DC);
// Zeiger auf den Globalen Speicher freigeben GlobalUnlock(HDib);
// Bitmap enthält jetzt einen Handle auf DDB |
ps. De Code habe ich nicht getestet. Er soll lediglich als ein Beispiel zur
Vorgehensweise dienen.
Matthias
(11.10.02 20:27 Tino) Code-Tags hinzugefügt.
|
|
Aya 
      
Beiträge: 1964
Erhaltene Danke: 15
MacOSX 10.6.7
Xcode / C++
|
Verfasst: Di 08.10.02 01:22
mh.. und wie kann ich da jetzt jedem einzelnen Pixel ne Farbe zuweisen? 
|
|
Addy
      
Beiträge: 43
|
Verfasst: Mi 09.10.02 11:16
@Matthias: Bist du ganz sicher, dass ein DIB die schnellere Variante ist? Ein DIB ist nämlich ein vom Device unabhängiger (allgemeiner) Bitmap, während ein DDB auf das Device "zugeschnitten" ist und von daher schneller sein müsste.
|
|
OregonGhost
      
Beiträge: 215
|
Verfasst: Fr 11.10.02 18:48
Man verwendet deshalb DIBs, weil man dann immer gleich arbeiten kann. In einer Bildbearbeitung kannst du so beispielsweise immer in 32bit arbeiten. Aber probier mal, zum Beispiel einen Transparenzeffekt mit 8bit zu zeichnen, nur weil der User das als Bildschirmfarbtiefe gewählt hat. Und als nächstes hat er vielleicht 4bit gewählt. Und dann 16bit.
Von daher sind DIBs nicht unbedingt schneller, aber es entfallen lästige Umrechnungen seitens des Programmierers, die sehr zeitintensiv sein können und außerdem sehr fehleranfällig sind.
Mit SetDIBitsToDevice() kann man übrigens statt in eine Bitmap die DIB direkt aufs Fenster zeichnen (bzw. natürlich in den Gerätekontext des Fensters).
_________________ Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
|
|
Addy
      
Beiträge: 43
|
Verfasst: Sa 12.10.02 09:12
Man lernt doch nie aus... 
|
|