Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi TShape + Canvas (https://www.delphipraxis.net/3990-tshape-canvas.html)

Schwanengel 10. Apr 2003 14:18


TShape + Canvas
 
Hallo
Ich habe folgende Fragen: :?:
Hat ein 'TShape' eigentlich auch einen 'Canvas'? wenn ja, wie kann ich auf diesen zugreifen?
Ich arbeite mit 'Delphi2.0' und möchte gern eine Transparente Ablage,
für ein TBitmap welches Transparente Bereiche enthält.
Falls man eine neue Komponente von TShape ableiten könnte, die ein Canvas enthält bitte ein Beispiel.
Meine Kenntnisse, über die Erstellung von Komponenten ist nicht gerade
groß.

Danke für Antworten

Daniel B 10. Apr 2003 15:04

Hallo,

ich werde es erstmal nach Multimedia verschieben.

Grüsse, Daniel :hi:

Schwanengel 11. Apr 2003 13:09

Hallo

Danke für die unheimlich vielen Antworten, aber ich hab's schon selber gefunden.
Das 'TShape' besitzt kein eigenes Fenster, wenn ich das so richtig verstanden habe. :!:

Wo :?:
bekommt man ausführliche Infos über die Erstellung von 'Komponenten'

Auch wenn ich nur Delphi2.0 habe... :roll:

oki 11. Apr 2003 13:26

Hi Schwanengel,

also, der Canvas und ein eigenes Fenster sind zwei unterschiedliche Sachen. TShape ist von TControl abgeleitet und besitzt somit von Hause aus keinen Canvas. Hier kannst du nur mittels API-Routinen über den Device-Context zugreifen.

In den letzten Tagen hatte ich mit hansa eine Diskussion zum Thema "Button selbst zeichnen". Der ist auch irgentwo ein TControl und die Themen würde ich als gleichwertig betrachten. Schau dort mal nach und benutze einfach die Suchfunktion des Forums.

Warum willst du überhaupt auf einen Canvas bei TShape zugreifen?

Gruß oki

Schwanengel 11. Apr 2003 15:29

HI OKI

Mein Grundproblem ist eigentlich folgendes,
(bitte nicht vergessen ich habe Delphi2.0) :!:

Ich habe ein Zeichenprogramm geschrieben wo die Zeichenfläche eine TImage ist.
Jetzt möchte ich aber weitere Bilder über dieser Zeichenfläche
Transparent positionieren können.
Wie ich denke benötige ich eine Komponente die das Bild aufnehmen kann
und die Transparent zu machen geht.

Danke für Deine Antwort....

oki 12. Apr 2003 20:43

Hi,

also, ich hab leider noch kein Zeichenprogramm geschriegen. Aber da Graphik auch an anderer Stelle benötigt wird, kommt einem da so einiges über den Weg. Schau mal in die Ecke TBitmap. In diesem Bereich findest Du auch einige Methoden um in einen Canvas zu zeichnen. Canvas.Draw ist ein Bsp.

In der Ecke TImageList kannst du auch recht einfach mehrere Bitmap' halten.

Hier bist du aber auf vorgefertigte Sachen angewiesen. Für das normale Zeichnen mußt du halt auf die Standardmethoden Lineto ... zurückgreifen.

Ich hab aber immer noch nicht so richtig verstanden was Du genau willst und wo dein Problem wirklich steckt. Was soll eine transparente Ablage sein?

Gruß oki

Schwanengel 13. Apr 2003 13:53

Hi oki,

ich möchte so eine Art wie Stempel, mit Hilfe einer Transparenten
Komponente erstellen. Dieser muß Transparent sein um eine teils Transparente 'TBitmap' aufzunehmen. Ich möchte bei der Positionirung
genau sehen wo ich hin stemple.
Gedanke:
Wenn es aber auch geht, dieses Teils transparente 'TBitmap' sichtbar
an die Maus zu hängen(egal welche Größe) würde es auch reichen.

Von Mirilin hatte ich schon den Hinweis erhalten, eine TPaintbox zu verwenden. (danke)

Momentan bin ich dabei dieses zu Probieren. :coder:
Frage:
Wenn ich die TPaintbox auf 'brush.style:=bsclear' stelle wird sie dann
auch Transparent.
Frage:
Wie kann ich in einer TImagelist eine Farbe bestimmen, die durch transparent ersetzt wird.

Danke...

oki 14. Apr 2003 08:22

Hi Schwanengel,

erst mal auf die Schnelle.

Wenn du dir eine Werkzeugleiste baust, also ein neues Formular mit der Eigenschaft FormStyle := stayontop und BorderStyle := bs ToolWindow, dann hast du schon mal was zum sammeln Deiner Strempel. Dort dann eine ToolBar rein und soviele Buttons wie Stempel anlegen. Eigenschaft Flat für Buttons macht sich bestimmt gut. Die Buttons-Bitmaps aus deiner ImageList auswählen. Button-Eigenschaft Style auf tbsChecked setzen. Jetzt kannst du deinen "Button-Stempel" durch auswählen (bleibt gedrückt) setzen.

Setze in die Ereignisbehandlungsroutine für OnMouseMove über deinem Zeichnungsobjekt das Zeichnen eines Rectangels in der Größe deines Stempels. Dann siehst du den Umriß deines Stempels beim Bewegen über der Zeichenfläche. Vergiß das Löschen des Rechtecks nicht!

Ich muß jetzt grad mal schluß machen. Den Rest später.

Gruß oki

oki 14. Apr 2003 11:31

Hi Schwanengel,

jetzt gehts weiter. Wenn du ein Bitmap in die ImageList aufnimmst hast du im oberen Bereich des Editors die Möglichkeit eine Transparentfarbe zu bestimmen. Das tust du einfach und dein Problem ist gelöst.

Leider kenne ich aktuell den Kompo-Umpfang von Delphi 2 nicht mehr aus dem Kopf. Ich arbeite mit Delphi 5. Zur Not mußt du das Thema Transparent über Umwege in der TBitmap lösen. Ich will jetzt nichts falsches sagen, aber schau mal im TBitmap unter Mask nach. Ich glaube das hat irgentwie was mit der Transparentfarbe zu tun. Bin mir aber nicht sicher, da ich damit noch nicht gearbeitet habe.


Gruß oki

Schwanengel 14. Apr 2003 12:01

Hi oki

alles klar mit der Einstellung.

Jetzt kommt das große aber, wie wird dieses zur Laufzeit des programmes eledigt.
Ich möchte die Imagelist zur Laufzeit füllen und auslesen... :roll:

oki 14. Apr 2003 12:15

Hi,

kein Thema. Schau in der Hilfe zum TImageList nach. Da gibt es Methoden wie AddIcon welche den Index der Position in der Imageliste zurückliefern.

Du mußt dann natürlich alle weiteren Elemente auch zur Laufzeit erstellen (Buttons in Wergzeugleiste usw.).

Gruß oki

Schwanengel 14. Apr 2003 17:29

Hallo,

schön und gut, aber hat so ein icon nicht eine begrenzte Größe :?:

Sollte ich mich dazu entschließen diese Methode zu verwenden, kommt
schon wieder ne' Frage...

Wie geht man vor, wenn man eine Pxelgafik erstellen möchte. :?:

(So in der Art, wenn man icons erstellt)

Kommt dann dieses Gitter (ab bestimmten Zoom) automatisch, oder muß dieses programmiert werden. :?:

Du siehst ich bin ein Mensch mit vielen Fragen. Ich bin auch froh dieses
Forum gefunden zu haben. :bounce2:

Ein bischen Lob muß auch mal sein... :party:

oki 15. Apr 2003 08:43

Oh Schwanengel,

du brauchst Nachhilfe in Graphik!

Also erste Frage. Das mit der ImageListe geht auch mit Bitmaps und nicht nur mit Icons.

Zweite Frage. Bitmaporientierte Graphiken sind immer "pixelorientiert".
Wenn du dort um den Faktor X vergrößerst bekommst du diese bekannte "Rasterung" mit dem Faktor X. Um das zu vermeiden gibt es Vectorgraphik. Einfach gesagt wird dort das Zeichnungsobject beschrieben, so nach dem Motto "Zeichne linie mit Breite x von Punkt a nach Punkt b. Dan wird immer die Beste Auflösung des Ausgabegerätes benutzt. Das war jetzt alles sehr grob und einfach gesagt, trifft aber in etwa den Grundsatz.

Bleib aber auf der Bitmap-Ebene, sonst wirst du nie mit dem Programm fertig. Ich bin leider wieder knapp in der Zeit. Melde mich vielleicht heute noch.

Gruß oki

Schwanengel 15. Apr 2003 11:44

Hi oki, :hi:

heute geht's weiter mit der Fragerei.
Ich hatte mir vor einiger Zeit Delphi2.0 gekauft mit allen Büchern die vorrätig waren.
Ich habe damals den Sprung in's eiskalte Wasser gewagt und den Versucht gestartet mir alles selbst anzueignen. (nie programmiert) :freak:
Mich hat die eigene Krativität bei solchen Dingen gelockt.
Aber wie man sieht hapert es bei manchen Dingen ebend und die ewige Sucherei nach Erklärungen macht einen krank..

Ich bin ja auch schon dabei, mit der Imagelist zu experimentieren. :coder:

Aber es fehlen mir ein paar Beispiele zur Umgehensweise. Die Erklärung in der Hilfe ist nicht immer leicht zu verstehen für so einen wie mich.

Aber erstmal vielen Dank für Deine Hilfe,
es bringt einen schon weiter...

oki 15. Apr 2003 16:00

Ja nu,

stell deine nächste Frage.

Gruß oki

Schwanengel 15. Apr 2003 17:52

Hallo :hi:

ich bekomme das nicht hin. :mrgreen:
Mein Experiment sieht so aus, ich habe zwei Buttons Kopie und Transparent:

Delphi-Quellcode:
procedure TForm1.SpeedButton4Click(Sender: TObject);
var //Button Transparent
  Bmp1,bmp3: TBitmap;
  bmpList: TImageList;
begin
   Bmp1 := TBitmap.Create;
   bmp3 := TBitmap.create;
  try
   bmp1.width:=blatt.width;
   bmp1.height:=blatt.height;
   bmp3.width:=blatt.width;
   bmp3.height:=blatt.height;
  Bmp1.Assign(blatt); //Blatt ist das Bitmap aus Zeichen Canvas
  bmpList := TImageList.CreateSize(bmp1.Width,bmp1.Height);
  bmplist.AddMasked(bmp1,bmp1.transparentcolor);
 try
   bmpList.Getbitmap(0, bmp3);
   blatt.canvas.brush.color:=clnone;
   blatt.canvas.brush.style:=bsclear;
   paintbox1.canvas.brush.style:=bsclear;
{Paintbox1 nimmt das Bild auf welches unter onPaint mit
Paintbox1.canvas.draw(0,0,blatt); immer wider nachgezeichnet wird.
Blatt wurde zuvor durch copyrect mit einem Bitmap, weches einen bestimmten Bereich der Zeichen Canvas enthält geladen.}
   blatt.assign(bmp3);
  finally
   bmpList.Free;
  end;
   finally
   bmp1:=nil;
   bmp3:=nil;
 end;
end;
Im Zweiten Versuch habe ich unter 'BitBlt' mal alles versucht und bin zu diesm Ergebnis gekommen. :coder:

Delphi-Quellcode:
bmp1,bmp2:tbitmap;
x,y: integer;
r:TRect;
begin
 bmp1:=tbitmap.create;
 bmp2:=tbitmap.create;
 bmp1.canvas.brush.style:=bssolid;
 bmp1.assign(blatt);
  x:=bmp1.Width;
  y:=bmp1.Height;
  bmp2.Width:=x;
  bmp2.Height:=y;
 bmp2.canvas.brush.style:=bsclear;
  r:=Rect(0,0,x,y);
  bmp2.Canvas.BrushCopy(r, bmp1, r,clwhite);
  BitBlt(bmp2.Canvas.Handle,0, 0, x, y,bmp1.Canvas.Handle, 0,0,PATCOPY);
  blatt.assign(bmp2);
 end;

Hier hat man den Hintergrund vom Desktop mit kopierter Zeichnung, immer wieder lustig. Was ist alles falsch :?:
Oder hab' ich was gefunden was es gar nicht gibt unter Delphi2.0 :?:

gruß Schwani

oki 17. Apr 2003 08:18

Hi Schwanengel,

gib mal dein ganzes Projekt rüber. Da kann ich dann mal selber ausprobieren wo dein Problem steckt.

Gruß oki

(am Besten heute noch, dann kann ich über Ostern mal raufschauen)

Schwanengel 18. Apr 2003 07:32

Liste der Anhänge anzeigen (Anzahl: 1)
Hi oki,

mein Testprogramm habe ich als selbstentpackende Zip-Datei mit den
Namen 's-Paint' zurecht gemacht.
Warte gespannt auf Antwort...






so das wars und noch schöne Feiertage.

oki 28. Apr 2003 13:25

Hi Schwanengel.

Tut mir leid, dass ich dich so lange warten lassen habe. Aber ich hab mir dein Projekt jetzt mal angeschaut.

Die Zielrichtung für die Transparenz Deiner kopierten Ausschnitte ist in der Richtung einer Logischen Verknüpfung auf die Hintergrundfarbe deiner Zeichenfläche zu suchen. So nach dem Motto:

-> Ergibt die logische AND-Verknüpfung deines aktuellen Pixels deiner Kopie mit der Hintergrundfarbe keine 1, so zeichne das bestehende.

Oh, da kommt der nächste Termin. Melde mich später.

Gruß oki

Schwanengel 29. Apr 2003 20:43

Hallo Oki!

ich freue mich ja das Du Dich mit meinem Problem befasst. Wie ich sehe könnte es zu lösen sein.
Ich habe in der Zwischenzeit auch noch einiges probiert, aber ohne
Erfolg!

oki 30. Apr 2003 11:02

Hi Schwanengel,

leider komme ich zeitlich etwas ins schleudern. Theoretischer Ansatz ist das eine (auch mal schnell gemacht). Praktisch lösen ist das andere (und dauert meistens).

Mein letzter Hinweis hört sich ja recht gut an, aber im Moment dokter ich auch recht erfolglos rum.

Im Moment müßten wir beide erst mal klären, wie der Kopierforgang auf deine Zeichenfläche erfolgen soll. Zur Zeit haben wir ja nur deine "Kopie-Paintbox" die wir verschieben können.

Dabei ist mir aufgefallen, dass es besser ist, wenn diese mit begin des kopierens zur laufzeit erstellt, und nach dem Platzieren und kopieren auf die Zeichenfläche entfernt wird. Ob man sinnvoll eine Paintbox nimmt müßte auch noch geklärt werden. Aber wir können ja mal so anfangen.

So, nun würde ich empfehlen, hier ein eigenes Objekt zu erstellen, dass wir von der Paintbox ableiten. Ich glaube, da kannst du am meisten lernen.

Leg mal ein neues Objekt der class TPaintBox an und wenn du nicht weiter kommst helf ich dir.

Hinweis: Auch wenn du das für einen Weg hällst der an deinen aktuellen Problemen vorbeiführt, glaub mir, das ist der richtige!

Gruß oki

Schwanengel 30. Apr 2003 20:18

Hi Oki,

es geht mir in diesem Fall ja wirklich nur um die Transparenz.
Sämtliche anderen Probleme sind im richtigen Programm schon alle gelößt.
Ehrlich gesagt wenn ich jetzt anfangen soll, eine Komponente zu entwickeln wie Du meinst, finde ich das ja auch richtig und schön.
Aber hierin besteht ja mein Problem, absolut keine Ahnung. :roll:
Ich habe ne' Menge Bücher aber nirgendwo ist das so richtig beschrieben.
Also habe ich nur mit den Komponenten experimentiert die mir zur Verfügung stehen.
Ich müßte also bei null beginnen. Wie man eine neue Komponente erzeugt und wie sie installiert wird weiß ich, daß ist aber auch alles.

Schwanengel 5. Mai 2003 07:01

Hi Oki, :dancer:

wie ich so sehe hast Du immer wenig Zeit.
Ich hatte am Sonntag einen Geistesblitz, erzeugte eine Funktion in der alle notwendigen Operationen enthalten sind.
Die alle Arbeit übernimmt und fügte sie an der richtigen Stelle ein. :coder:
Jetzt habe ich alles wie es sein soll.
Bei Colorbildern bekommt der Computer ganz schön was zu tun, aber es geht.
Den Vorschlag mit dem Vergleich zwischen zwei Bildern geht in der
Form nicht, da ja alles bei "Dragg"(aus S_Paint zu ersehen) ablaufen muß und da bricht alles zusammen. Ich bin auch von der blöden Paintbox wieder weg, hatte ja am Anfang schon mit TImage begonnen also jetzt weiter damit.
Aber um auf Deinen Vorschlag zurück zu kommen, ein neues Objekt anzulegen. Ich habe da volle Interesse dran. Wenn du mir sagen könntest
wo ich zum Anfang was nachlesen kann.

Warte gespannt auf Deine Antwort....

oki 5. Mai 2003 08:25

Hi Schwanengel.

Schön, dass du von alleine auf die TImage-Komponente gekommen bist. Das währe jetzt mein nächster Tip für die Transparenz gewesen.

Du sagst, dass du eine Methode eingefügt hast, die Dir viel Arbeit abnimmt.
Das ist schon der erste Schritt zum Object-Glück.

Mal was allgemeines vorweg. Es währe doch schön, wenn du dir in deinem Hauptprogramm nicht alles merken mußt für die Operationen deiner kopierten Zeichnungen. Also merkt mal sich das doch am Besten in einem Objekt und sagt diesem immer nur was aktuell passiert um es dann reagieren zu lassen.

Einfach gesprochen sieht das so aus.

Das Kopie-Object soll erstellt werden: also kreieren!

Du willst mit dem verschieben anfangen: also bescheid sagen!

Du bewegst die Maus: also bescheid sagen!

Die Kopie ablegen: also bescheid sagen!

Fertig: also Object zerstören(destroy)!

Wie macht man das?

Du hast selber gemerkt, dass ein TImage ideal für deine Aufgabenstellung ist.

Nun gut, dann ist unser neues Object von der Klasse TImage abgeleitet.
Das sieht so aus:

Delphi-Quellcode:
type
  TCopyImage = class(TImage)
  private
 
  public

  end;
In Private und Public schreiben wir dann alle notwendigen Eigenschaften und Methoden die wir so brauchen.

Gib mir mal deinen aktuellen Code rüber und ich mach mal einen Anfang.

Gruß oki

oki 14. Mai 2003 08:09

Hi Schwanengel,

ich wollte mal horchen ob's dich noch gibt. Wie kommst Du mit deinem Projekt vorwärts und brauchst Du noch meine Hilfe?

Gruß oki

Pseudemys Nelsoni 14. Mai 2003 10:03

is delphi 2 gut?

Schwanengel 17. Mai 2003 06:56

Hi

Die letzte Frage zuerst: "Delphi2 ist nicht unbedigt das beste,
Aber alles was ich bis jetzt machen wollte
ging damit.! " (Geldmangel)

Jetzt weiter:
Hi Oki mich bit's noch.
Ich habe durch die "Function" die mir in den Sinn kam, schon wieder eine
neue Idee gehabt.
Daraus entstand ein neues Programm. Ich habe eine neue Frage, ohne jetzt
das andere Problem zu vergessen.(Komponentenentwicklung)
Ich benutze wieder das bewuste verchieben, was wir bis jetzt besprochen haben...

Frage:
Wie kann ich dieses zweite Bild (Image2) welches ich auf dem
Untergrund (Image1) verschiebe, an bestimmten Rasterpunkten
die in der unteren Image (Image1) sind einrasten lassen.

Gruß Schwanengel

oki 19. Mai 2003 11:19

Hi Schwanengel.

Ich habe gerade ein ähnliches Problem bearbeitet. Zur Umsetzung des Themas "Einrasten an bestimmten Punkten" würde ich noch mal die Aufgabe klar definieren.

Die Frage ist erst mal, ob das "Einrasten" an einer Art Gitter, oder an bestimmten Punkten erfolgen soll.

Bei einem Gitter würde ich im Image1 das Gitter definieren und das Einrasten zur Laufzeit berechnen.
Bei definierten Punkten die Punkte setzen und weitere Parameter wie Entfernung vom Punkt für Einrasten usw. festlegen. Genauso müßte hier geklärt werden, ob es eine feste Anzahl von Einrastpunkten oder eine beliebige gibt. Dementsprechend flexiebel muß die Verwaltung dann laufen.

Ist das alles getan, können wir mit einer einfachen eigenen Funktion von Image1 die Korrektur der Koordinaten vornehmen lassen. Die würde dann so aussehen:
Delphi-Quellcode:
Function GetRastPoint(Value : TPoint) : TPoint;
begin
  Result := Value;
  // befinden sich die koordinaten in der Nähe eines Einrastpunktes?
 
  // wenn nicht raus!

  // wenn ja, Koordinate des Einrastpunktes Result zuweisen!
end;
Die Funktion GetRastPoint kann vor Positionierung der Graphik aufgerufen werden, wobei die Position der Platzierung dann mit dem Rückgabewert erfolgt.

Für die Einrast-Koordinaten sag mal bescheid, welche der oben erwähnten Methoden du brauchst. Dann machen wir da was anständiges draus.

Gruß oki


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