Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Canvas drucken (https://www.delphipraxis.net/174222-canvas-drucken.html)

Masterofdesasta 10. Apr 2013 08:55

Canvas drucken
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo erstmal...
Mein Problem besteht darin:
Hab ein Programm geschrieben welches Graphen über Canvas zeichnen kann. Die gesamten Graphen und das Koordinatensystem befindet sich im Gebiet(0,0,800,800). Ich hab einen 'Drucken' Button... was muss ich in die procedure des Buttons hineinschreiben damit er nur das Koordinatensystem + Graphen druckt?

Andreas L. 10. Apr 2013 09:01

AW: Canvas drucken
 
In etwa so:

Delphi-Quellcode:
  Printer.BeginDoc;
  try
    Printer.Canvas.Assign(DeinCanvas); // evtl. musst du dein Canvas mit Draw, etc. auf das Printer-Canvas zeichnen
  finally
    Printer.EndDoc;
 end;
Siehe http://docwiki.embarcadero.com/Libra...inters.Printer

Masterofdesasta 10. Apr 2013 09:25

AW: Canvas drucken
 
Danke erstmal für die Antwort.
Leider hab ich keine Ahnung wenn du z.B. schreibst DeinCanvas... prog noch net solang :)
Könntest du es mir etwas einfacher erklären?

Bummi 10. Apr 2013 09:43

AW: Canvas drucken
 
Wenn Du Deine Zeichenroutine universell implementierst, kannst Du ein und diese Routine für die Ausgabe auf dem Bildschirm, dem Drucker oder auch in ein BMP,Metafile etc. verwenden.
Nur als grober Anriss, zum feinschleifen:

Delphi-Quellcode:
unit Unit3;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm3 = class(TForm)
    PaintBox1: TPaintBox;
    Drucken: TButton;
    procedure PaintBox1Paint(Sender: TObject);
    procedure DruckenClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form3: TForm3;

implementation

{$R *.dfm}

uses Math, Printers;

Procedure SetCanvasZoomAndRotation(ACanvas:TCanvas;Zoom:Double;Angle:Double;CenterpointX,CenterpointY:Double);
var
    form : tagXFORM;
    Winkel:Double;

begin
      Winkel := DegToRad(Angle);
      SetGraphicsMode(ACanvas.Handle, GM_ADVANCED);
      SetMapMode(ACanvas.Handle,MM_ANISOTROPIC);
      form.eM11 := Zoom * cos( Winkel);
      form.eM12 := Zoom *Sin( Winkel) ;
      form.eM21 := Zoom * (-sin( Winkel));
      form.eM22 := Zoom * cos( Winkel) ;
      form.eDx := CenterpointX;
      form.eDy := CenterpointY;
      SetWorldTransform(ACanvas.Handle,form);
end;




Procedure DoThePaint(C:TCanvas;Width,Height:Integer);
Const
 C_PaintRaster:TRect=(Left:-100;Top:-100;Right:100;Bottom:100);// Dein Koordinatensystem
var
  x,y:Integer;
  Zoom:Double;
  i:Integer;
begin

    Zoom := Width /(C_PaintRaster.Right-C_PaintRaster.Left); // hier gegf. einen geeigneteren Algorhytums
    SetCanvasZoomAndRotation(C,Zoom ,0,-C_PaintRaster.Left * Zoom ,-C_PaintRaster.Top * Zoom);

    // irgendeine Demozeichenroutine
    c.Font.Size := Round(10 / zoom);
    c.Brush.Style := bsClear;
    for I := -100 to 100 do
        if (i mod 10)=0 then
          begin
           C.Ellipse(i-5,i-5,i+5,i+5);
           c.TextOut(i-2,i-2,IntToStr(i));
          end;

end;

procedure TForm3.DruckenClick(Sender: TObject);
begin
  Printer.Begindoc;
  DoThePaint(Printer.Canvas,Printer.PageWidth,Printer.Pageheight);
  Printer.EndDoc;
end;

procedure TForm3.PaintBox1Paint(Sender: TObject);
begin
   DoThePaint(PaintBox1.Canvas,PaintBox1.Width,PaintBox1.Height);
end;

end.

Andreas L. 10. Apr 2013 09:53

AW: Canvas drucken
 
Zitat:

Zitat von Masterofdesasta (Beitrag 1210967)
Danke erstmal für die Antwort.
Leider hab ich keine Ahnung wenn du z.B. schreibst DeinCanvas... prog noch net solang :)
Könntest du es mir etwas einfacher erklären?

In deinem ersten Post steht das du dein Koordinatensystem auf ein Canvas zeichnest. Und dieses Canvas muss an das Printer.Canvas übergeben werden. Oder du zeichnest das Koordinatensystem direkt auf das Printer.Canvas. Damit du nicht doppelten Code für das Zeichnen schreibst, machst du dir eine Routine der du das Canvas übergeben kannst:

Delphi-Quellcode:
procedure DrawToCanvas(ACanvas: TCanvas);
begin
  ACanvas.LineTo(..);
  ...
  ...
end;

// Aufruf:

DrawToCanvas(PaintBox1.Canvas); // auf eine PaintBox zur visuellen Darstellung malen
DrawToCanvas(Printer.Canvas); // auf den Printer zum drucken malen
Also in etwa so wie Bummi es schon geschrieben hat.

uligerhardt 10. Apr 2013 09:58

AW: Canvas drucken
 
Du hast doch momentan irgendwo Code, der auf den Canvas einer PaintBox o.ä. malt. Den musst in eine Prozedur a la
Delphi-Quellcode:
MalDenGraphen(ACanvas: TCanvas)
verpacken. Diese Prozedur kannst du dann einmal als
Delphi-Quellcode:
MalDenGraphen(PaintBox.Canvas)
und einmal als
Delphi-Quellcode:
MalDenGraphen(Printer.Canvas)
aufrufen.

Edit: Roter Kasten? Haaaaalllllllo? :mrgreen:

Masterofdesasta 10. Apr 2013 10:13

AW: Canvas drucken
 
Wieder danke für die ganzen Antworten :)
Leider ist selbst das wirklich noch zu kompliziert :( (Besonders das von Bummi)
So weit bin ich leider noch nicht...

Ich glaube aber herausgelesen zu haben das canvas irgendwie ein Objekt ist o.O ...
Vieleicht hab ich mich falsch ausgedrückt(wenn ja sryyyyy). Aber ich zeichne mein Koordiantensystem einfach so:
Code:
   canvas.MoveTo(50,400);    //x-Achse
   canvas.LineTo(750,400);
   canvas.MoveTo(400,50);    //y-Achse
   canvas.LineTo(400,750);
   canvas.MoveTo(225,575);   //z-Achse
   canvas.LineTo(575,225);
Und meinen Graphen so:
Code:
if (a<>0) or (b<>0) or (c<>0) or (d<>0) then begin
                                                 canvas.Pen.Color:=rgb(random(256),random(256),random(256));
                                                 canvas.Pen.Width:=2;
                                                 x:=-7;
                                                 xl:=50;
                                                 repeat begin
                                                           y:=a*x*x*x+b*x*x+c*x+d;
                                                           canvas.MoveTo(xl,400-round(y*50));
                                                           xl:=xl+1;
                                                           x:=x+0.02;
                                                         end;
                                                 until ((400-round(y*50))<751) and ((400-round(y*50))>49);
                                                 repeat begin
                                                           y:=a*x*x*x+b*x*x+c*x+d;
                                                           if ((400-round(y*50))<751) and ((400-round(y*50))>49) then canvas.LineTo(xl,400-round(y*50))
                                                                                                                 else canvas.MoveTo(xl,400-round(y*50));
                                                           xl:=xl+1;
                                                           x:=x+0.02;
                                                         end;
                                                 until xl=751;
                                               end;
Naja... so in etwa... Ich such wirklich nur eine Möglichkeit dies zu drucken :S

Sir Rufo 10. Apr 2013 10:24

AW: Canvas drucken
 
Es gibt einen Bildschirm-Canvas und einen Drucker-Canvas.

Beide reagieren völlig gleich, nur dass der eine auf den Bildschirm malt und der andere auf den Drucker.

Wie kommst du denn an dein Canvas Objekt was du benutzt?
Irgendwo hast du ja stehen
Delphi-Quellcode:
  // Canvas merken
  canvas := ...
 
  canvas.MoveTo(50,400);   //x-Achse
  canvas.LineTo(750,400);
  canvas.MoveTo(400,50);   //y-Achse
  canvas.LineTo(400,750);
  canvas.MoveTo(225,575);  //z-Achse
  canvas.LineTo(575,225);
oder
Delphi-Quellcode:
with ... do
  begin
    canvas.MoveTo(50,400);   //x-Achse
    canvas.LineTo(750,400);
    canvas.MoveTo(400,50);   //y-Achse
    canvas.LineTo(400,750);
    canvas.MoveTo(225,575);  //z-Achse
    canvas.LineTo(575,225);
  end;

uligerhardt 10. Apr 2013 10:43

AW: Canvas drucken
 
Zitat:

Zitat von Sir Rufo (Beitrag 1210979)
Wie kommst du denn an dein Canvas Objekt was du benutzt?
Irgendwo hast du ja stehen
Delphi-Quellcode:
  // Canvas merken
  canvas := ...
 
  canvas.MoveTo(50,400);   //x-Achse
  canvas.LineTo(750,400);
  canvas.MoveTo(400,50);   //y-Achse
  canvas.LineTo(400,750);
  canvas.MoveTo(225,575);  //z-Achse
  canvas.LineTo(575,225);
oder
Delphi-Quellcode:
with ... do
  begin
    canvas.MoveTo(50,400);   //x-Achse
    canvas.LineTo(750,400);
    canvas.MoveTo(400,50);   //y-Achse
    canvas.LineTo(400,750);
    canvas.MoveTo(225,575);  //z-Achse
    canvas.LineTo(575,225);
  end;

... oder du bist im FormPaint und benutzt den Canvas der Form selbst?

Sir Rufo 10. Apr 2013 10:55

AW: Canvas drucken
 
BTW

Delphi-Quellcode:
repeat
  begin
    ...
  end;
until SomeState;
ist nicht unbedingt falsch aber es reicht vollkommen
Delphi-Quellcode:
repeat
  ...
until SomeState;
Dann wäre es auch schön, wenn du die Delphi-Tags verwenden würdest
Code:
[DELPHI]
// hier Delphi-Code
[/DELPHI]
und die Formatierung ist ... "abenteuerlich" :mrgreen:

So könnte das dann aussehen
Delphi-Quellcode:
  if ( a <> 0 ) or ( b <> 0 ) or ( c <> 0 ) or ( d <> 0 )
  then
    begin
      canvas.Pen.Color := rgb( random( 256 ), random( 256 ), random( 256 ) );
      canvas.Pen.Width := 2;
      x               := - 7;
      xl              := 50;

      repeat
        y := a * x * x * x + b * x * x + c * x + d;
        canvas.MoveTo( xl, 400 - round( y * 50 ) );
        xl := xl + 1;
        x := x + 0.02;
      until ( ( 400 - round( y * 50 ) ) < 751 ) and ( ( 400 - round( y * 50 ) ) > 49 );

      repeat
        y := a * x * x * x + b * x * x + c * x + d;
        if ( ( 400 - round( y * 50 ) ) < 751 ) and ( ( 400 - round( y * 50 ) ) > 49 )
        then
          canvas.LineTo( xl, 400 - round( y * 50 ) )
        else
          canvas.MoveTo( xl, 400 - round( y * 50 ) );
        xl := xl + 1;
        x := x + 0.02;
      until xl = 751;
    end;

Bjoerk 10. Apr 2013 11:30

AW: Canvas drucken
 
Ich würde sagen, am einfachsten ist es, strukturiere das Programm so, daß du ein Canvas als Parameter mitschicken kannst. Dann kannst du sogar auf ein MetafileCanvas zeichen. Zum Drucken braucht du dann nur ein Printer.Canvas.StrechDraw(…., MetaFile).
Analog die Ausgabe am Bildschirm. Zum MetaFile gbt's hier im Forum ein schönes Beispiel von DeddyH (TfrmMetaFileDemo oder so ähnlich).

Masterofdesasta 10. Apr 2013 19:17

AW: Canvas drucken
 
Liste der Anhänge anzeigen (Anzahl: 1)
:S ich versteh nur noch Bahnhof :(
Noch viel zu kompliziert für mich...

ich stell mir im endeffekt nur ein paar kurze anweisungen vor:

printer.drucken(0,0,800,800)
ich hab einfach keine Ahnung...

ich lad einfach mal meinen quelltext hoch x3 wenn jemand damit was anfangen kann wäre ich euch schwerstens verbunden :)

Bjoerk 10. Apr 2013 20:54

AW: Canvas drucken
 
Eigentlich ganz einfach. Das was du jetzt in den ButtonClicks stehen hast, hat dort eh nichts verloren. Das lagerst du in andere Prozeduren (oder noch besser in eine eigene unit oder Klasse) aus und gibst denen z.B. ein Canvas als Parameter oder die Klasse hat ein Feld Canvas o.ä.. Die Clicks rufen dann diese Prozeduren auf und versorgen sie mit den nötigen Infos aus der GUI. Bzw. die GUI hat eine Instanz der Klasse.

uligerhardt 10. Apr 2013 21:17

AW: Canvas drucken
 
Die Zeichenaufrufe gehören auch nicht in einen OnClick-Handler, sondern ins OnPaint der Form oder einer PaintBox. Windows funktioniert nämlich nicht so, dass du auf einen Canvas malst, und das Gemalte bleibt dann dort "ewig" drauf, sondern Windows veranlasst alle Naselang einen OnPaint-Aufruf, indem du dann alles neu zeichnen musst.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:00 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz