Autor Beitrag
mg80s
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 33

WinXP SP2
Delphi 6 Personal ;) , C# (VS 2003 Prof.)
BeitragVerfasst: Fr 07.10.05 09:46 
Hallo,

ich möchte auf ein Image, dass ein Bild geladen hat einige Boxen malen (Begrenzungrahmen etc).
Habe nun also erstmal versucht, per Canvas.MoveTo und LineTo zu zeichnen.

Dabei ist mir erstens bitter aufgestoßen, dass ich das nur machen kann, wenn die geladene Grafik eine Bitmap ist (sonst Fehlermeldung) und zweitens, dass das Image sobald ich zeichne Weiss wird (ausser dem Gezeichneten).

Was mir als Lösung einfiele, wäre folgendes, aber das kommt mir irgendwie zu aufwendig vor:

Die Pixel des geladenen Bilds kann ich ja in ein Array vom Type TColor ablegen. Dann zeichne ich nur die Begrenzungsrahmen etc (die alle Schwarz oder Rot sind). Danach schaue ich mir jedes Pixel an, wenn das noch Weiss ist, zeichne ich mit Pixels[x,y] die Farbe aus dem gespeicherten Array an diese Stelle.

Könnte das funktionieren? Bzw. kennt Ihr einen besseren Weg?

Edit: Sorry, sehe gerade, dass das evtl gar nicht hierhin gehört :oops:
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Fr 07.10.05 10:11 
Doch doch. Das ist hier schon ganz rchtig.

Streiche diese Idee mit dem 2D Array mal sofort wieder aus deinem Gedächtnis. Das einzige was du damit erreichen kannst ist, dass es super langsam wird. Die Canvas eines TImages bezieht sich auf die Bilddaten und sobald du dort hinein zeichnest veränderst du dein Bild. Ich persönlich würde da auch das TImage außen vor lassen. Warum erfreut sich das eigentlich so großer Beliebtheit??? Na ja. Egal.

Ich würde dir Empfehlen ein TPicture von Hand zu erzeugen und dein Bild dort hinein zu laden. Dann solltest du eine TPaintBox benutzen und in dieser das Bild an die gewünschte Stelle zeichnen. Wenn die PaintBox auf DoubleBuffered Panel sitzt, dann flackerts auch nicht. Zum Zeichnen kannst du dann den vollen bereich der Paintbox benutzen. Auch wenn das Bild nur 10x10 Pixel groß ist.

Folgender Code sollte ausreichen um das Bild zentriert und ohne Flackern darzustellen.
ausblenden Delphi-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:
procedure TForm1.FormCreate(Sender: TObject);
begin
  fPic := TPicture.Create;
  fPic.LoadFromFile('C:\WINNT\Seifenblase.bmp');

  Panel1.DoubleBuffered := True;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FreeAndNil(fPic);
end;

procedure TForm1.PaintBox1Paint(Sender: TObject);
begin
  with PaintBox1.Canvas do begin
    Draw(
      PaintBox1.ClientWidth div 2 - fPic.Width div 2,
      PaintBox1.ClientHeight div 2 - fPic.Height div 2, fPic.Graphic);

    Pen.Color := clYellow;
    Brush.Style := bsClear;
    Rectangle(14045300210);
  end;
end;


Die Sache mit den Farben habe ich nicht ganz verstanden. Wenn das noch eine Frage war, dann musst du das noch mal genauer erklären.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
mg80s Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 33

WinXP SP2
Delphi 6 Personal ;) , C# (VS 2003 Prof.)
BeitragVerfasst: Fr 07.10.05 10:21 
Aha, das wirft meine Pläne ja in eine vollkommen neue Richtung. Und auf diesem Wege bleibt dann das Bild erhalten und die Striche können beispielsweise auch durch das Bild gehen?
Was frag ich eigentlich...einfach mal ausprobieren :D Danke!!

Die Sache mit den Farben war eine Idee um mein Problem zu lösen.
Ich wollte zuallererst mal Pixel für Pixel die Farbwerte des Originalbildes in ein Array schubsen. Dann nur die neu zu zeichnenden Elemente darstellen. Dann wäre ja alles, wo nichts gezeichnet wurde Weiss. Und nun wollte ich alle Pixel, die Weiss geblieben sind, mit der Farbe versehen, die ich aus dem Originalbild an dieser Stelle geholt habe. Damit hätte es ausgesehen, als hätte ich die Striche über das Bild gemalt.

Aber hast schon recht, das ist einfach zu langsam, ich versuch mal Deinen Weg und meld mich nochmal :wink:
mg80s Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 33

WinXP SP2
Delphi 6 Personal ;) , C# (VS 2003 Prof.)
BeitragVerfasst: Fr 07.10.05 10:31 
Ähm, Problem.....das Bild flackert einmal kurz auf und verschwindet dann. Habe auch testweise zB das Rectangle und andere Teile auskommentiert, aber immer das gleiche Ergebnis. Zu früh gefreut? :)
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Fr 07.10.05 11:12 
Also bei mir funktioniert es wunderbar. Hmmm. Merkwürdig. Nicht, dass das ein Effekt zwischen D6 und D7 ist. Machst du sonst irgendetwas mit dem TPicture oder so. Oder siehst du dann gar nichts mehr? Na ja. Du könntest auch noch was anderes versuchen. Ich habe vor ner Weile mal ein Panel abgelitten und dafür gesorgt, dass es ein OnPaint und eine Canvas bekommt. Das habe ich zwar für OpenGL geschrieben aber das könntest du spaßeshalber ja mal ausprobieren. Du musst das entpacken und das Package (*.dpk) installieren. Anschließend musst du unter "Tools" -> "Umgebungsoptionen" -> "Bibliothek" -> "Suchpfad" den Pfad der Quellen angeben. Das findest du dann auf der Seite "Standard".

Ach ja. Nicht erschrecken, wenn du das auf dem Formular hast. Das wird nicht neu gezeichnet und sorgt so für ein paar Grafikfehler.

Dann kannst du damit dein Panel und die PaintBox ersetzen. Das DoubleBuffering solltest du bei dem auch setzen und im OnPaint solltest du es dann zu erst löschen. Wenn das getan ist kannst du es ganz normal bemalen.
ausblenden canvas löschen
1:
2:
3:
4:
5:
6:
7:
8:
9:
procedure TForm1.AdvancedPanel1Paint(Sender: TObject);
begin
  with AdvancedPanel1.Canvas do begin
    Brush.Color := clBtnFace;
    FillRect(ClipRect);

    // Normale weiter zeichnen
  end;
end;


PS: Wenn das auch nicht geht, dann muss es an etwas anderem liegen. Dann geb ich auf. ;-)

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
mg80s Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 33

WinXP SP2
Delphi 6 Personal ;) , C# (VS 2003 Prof.)
BeitragVerfasst: Fr 07.10.05 11:28 
Ich Depp!! :roll:

Erst lesen, dann nachdenken, dann Code abtippen... *einbläu*

Sorry, hatte den Quelltext in "PaintBox1Paint" nur einmal beim Laden des Bildes, also gleich aus dem ButtonClick heraus aufgerufen und da wurde's wohl nur einmal kurz am Anfang gezeichnet....

Dank Dir für Deine Bemühungen :D