Autor Beitrag
Aya
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 43



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 43



BeitragVerfasst: 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 :wink:
Aya Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 43



BeitragVerfasst: Mo 07.10.02 17:33 
Dann probier mal die API-Funktion SetDIBits, eventuell ist die schneller.
Matthias
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 121



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 121



BeitragVerfasst: 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:
ausblenden volle Höhe Quelltext
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1964
Erhaltene Danke: 15

MacOSX 10.6.7
Xcode / C++
BeitragVerfasst: Di 08.10.02 01:22 
mh.. und wie kann ich da jetzt jedem einzelnen Pixel ne Farbe zuweisen? :)
Addy
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 43



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 215



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 43



BeitragVerfasst: Sa 12.10.02 09:12 
Man lernt doch nie aus... :oops: