Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Suche Konzept: Bild mit unbekannter Größe (https://www.delphipraxis.net/185880-suche-konzept-bild-mit-unbekannter-groesse.html)

Cubysoft 14. Jul 2015 17:12

Suche Konzept: Bild mit unbekannter Größe
 
Hallo,

ich brauche heute eure Hilfe beim Finden eines geeigneten Konzepts. Dafür erkläre ich euch am Besten ersteinmal die Situation

Situation:

Ich lade während der Programmlaufzeit Daten in ein Record. Diese Daten möchte ich graphisch anzeigen, indem ich sie auf ein Canvas zeichne. Dies übernimmt eine eigene Klasse, was soweit auch wunderbar funktioniert. Das Problem hierbei ist nur, dass ich er NACH dem Zeichnen weiß, wie groß das ganze jetzt eigentlich ist. Die Größe ist hierbei nicht nur von wenigen Faktoren abhängig, sondern von vielen. Bisher habe ich das "Gemälde" immer schön auf eine Komponente (Testform.Canvas) gezeichnet, welche so groß war, dass immer alles gepasst hat.

Ich möchte nun aber die Malerei in einer TImage-Komponente fortsetzen und diese dann der Größe anpassen. Mein Konzept bisher ist, dass meine "Mal-Klasse" 2 Funktionen hat. Die erste zeichnet die Malerei, die 2. macht im Prinzip das selbe, gibt aber als Rückgabewert die Größe zurück. Sprich ich habe doppelte Rechnerei.

Meine Frage ist nun: Kann man das eventuell etwas vereinfachen?


Danke schonmal!

Luckie 14. Jul 2015 18:39

AW: Suche Konzept: Bild mit unbekannter Größe
 
Zeichne das ganze doch auf ein Bitmap im Speicher. Dann weißt du wie groß es wird und kannst es dann von da auf den Canvas des TImage kopieren.

Sir Rufo 14. Jul 2015 18:47

AW: Suche Konzept: Bild mit unbekannter Größe
 
Man kann das Berechnen und Zeichnen natürlich trennen.

Beim Berechnen erzeugt man die entsprechenden Zeichenroutinen und beim Zeichnen werden diese Routinen einfach abgearbeitet. Nach dem Berechnen bekommt man von jeder Zeichenroutine auch die Größe der benutzen Zeichenfläche und kann diese Rects einfach zusammenzählen.

Jetzt kann das auch in einer Paintbox gezeichnet werden (mit Zoom, Offset, etc.) weil nur noch die Zeichenroutinen abgespult werden und die Berechnung wegfällt.

Um das transparent zu machen, kann man sich eine Canvas-Klasse schreiben, die nicht zeichnet, dafür aber die Zeichenroutinen erstellt.

Cubysoft 14. Jul 2015 18:56

AW: Suche Konzept: Bild mit unbekannter Größe
 
Das Problem ist einfach, dass ich das ganze gerne so performant wie möglich hätte. Meine Idee, die ich habe ist relativ gut, aber ich habe keine Ahnung, inwieweit das umsetzbar ist. Kann ich nicht einfach so vorgehen:

- Bild auf Canvas zeichnen (Canvas(se) haben doch keine Ränder oder?)
- Wenn zeichnen fertig, dann TBitmap auf die Größe trimmen und das was ich ins Canvas gezeichnet habe einfügen
- Bitmap übergeben

In der Form:

- Bitmapgröße auslesen -> TImage auf diese Größe bringen
- Bitmap setzen

Wenn das so gehen würde wäre das perfekt.. :)

Bjoerk 14. Jul 2015 20:19

AW: Suche Konzept: Bild mit unbekannter Größe
 
Du könntest auch auf mm umsteigen (MMWidth, MMHeight, PenMMWidth ect.). Das erleichtert enorm die Arbeit und ist auch genauer. Zum Zeichen auf eine Bitmap/ Metafile ect. dann eine function MMToPixel o.ä. einführen.

Luckie 14. Jul 2015 21:02

AW: Suche Konzept: Bild mit unbekannter Größe
 
Was haben jetzt die Maßeinheiten mit dem Grundsätzlichen Problem zu tun?

Bjoerk 14. Jul 2015 22:08

AW: Suche Konzept: Bild mit unbekannter Größe
 
Als Referenzeinheit. Pixel hingegen ist nicht zu empfehlen. Irgendwie muß das Bild ja mal berechnet werden? Wenn das Bild in Floats vorliegt, kann man es sauber skalieren. Die spätere Darstellungsgröße in Pixel ist dann wurscht. Dadurch bekommt man auch bei vergleichsweise kleinen Abmessungen noch relativ scharfe Bilder.

Luckie 14. Jul 2015 23:00

AW: Suche Konzept: Bild mit unbekannter Größe
 
Ist doch alles Wurscht. Das alles spielt doch erst beim Ausdruck eine Rolle. Und warum sollte Pixel schlecht sein als Referenzeinheit? Das läuft doch alles intern ab. Und ein Canvas ist nur mal X Pixel breit und hoch. Oder stellst du die Formularbreite in Millimeter ein im Objektinspektor?

Aphton 14. Jul 2015 23:14

AW: Suche Konzept: Bild mit unbekannter Größe
 
lol @luckie.. ne.. nicht mm, aber inch!!

Luckie 14. Jul 2015 23:28

AW: Suche Konzept: Bild mit unbekannter Größe
 
Nicht römische Fuß oder Marburger Ellen?

Letztendlich fragt er nach einer prinzipiellen Lösung. Und da spielen die Einheiten keine Rolle.

Cubysoft 14. Jul 2015 23:43

AW: Suche Konzept: Bild mit unbekannter Größe
 
Ja, das hat alles bis jetzt nicht wirklich geholfen. Ich meine funktionieren würde die eine Variante ja, gefallen tut sie mir aber nicht. Gibt es wirklich keine Möglichkeit auf ein größeres Medium zu zeichnen und dann die Größe zu verändern? Wir eine TBitmap beim resizen geleert? Wenn nicht kann ich ja einfach ne 1000x1000 px große Bitmap erzeugen und am Ende verkleinern

Jens01 14. Jul 2015 23:58

AW: Suche Konzept: Bild mit unbekannter Größe
 
Ich verstehe Dich nicht so ganz, aber man könnte es so, wie Bjoerk es gemeint hat, machen. Man muß das, was Du da reinzeichnest, zu irgendwas relativ setzen. In der Schule was das -glaub ich- "Verhältnisrechnung".
Man kann natürlich auch das Bitmap skalieren, das ist aber nicht so einfach, wie man denkt. Dazu benötigst Du auch eine Engine.
Graphics32 hat ein TImage, das skalieren kann.

Ansonsten mußt Du Dein Problem näher beschreiben.

Gute Nacht!

Sir Rufo 15. Jul 2015 11:57

AW: Suche Konzept: Bild mit unbekannter Größe
 
Bei einem Bitmap, muss man vorher auch die Größe angeben, sonst habe ich zwar auf dem Canvas gemalt, aber in der Bitmap steht nichts drin.

Somit hat man also mit dem Bitmap nichts gewonnen.

Ein simple Alternative besteht (wie schon gesagt) die Zeichenroutinen ein zusammenzustellen, dabei stellt man eben auch die tatsächliche Größe fest und dann wird das Zeil auf diese Größe eingestellt und die Zeichenroutinen angewendet.

Hier ein ganz billiges Beispiel:
Delphi-Quellcode:
unit Form.MainForm;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class( TForm )
    Button1: TButton;
    Button2: TButton;
    PaintBox1: TPaintBox;
    ScrollBox1: TScrollBox;
    Panel1: TPanel;
    procedure Button1Click( Sender: TObject );
    procedure Button2Click( Sender: TObject );
    procedure PaintBox1Paint( Sender: TObject );
  private
    FPaintBoxProc: TProc<TCanvas>;
    procedure SetPaintBoxProc( const Value: TProc<TCanvas> );
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click( Sender: TObject );
var
  LProc: TProc<TCanvas>;
begin
  // Zeichenroutine zusammenstellen
  LProc :=
    procedure( Canvas: TCanvas )
    begin
      Canvas.Brush.Color := clRed;
      Canvas.Ellipse( 100, 100, 400, 400 );
      Canvas.Brush.Color := clBlue;
      Canvas.Rectangle( 350, 400, 800, 700 );
    end;

  // PaintBox Größe setzen
  PaintBox1.Width := 800;
  PaintBox1.Height := 700;

  // Zeichenroutine für die PaintBox setzen
  SetPaintBoxProc( LProc );
end;

procedure TForm1.Button2Click( Sender: TObject );
begin
  SetPaintBoxProc( nil );
end;

procedure TForm1.PaintBox1Paint( Sender: TObject );
begin
  // Hier wird die Zeichenroutine einfach ausgeführt
  if Assigned( FPaintBoxProc ) then
    FPaintBoxProc( ( Sender as TPaintBox ).Canvas );
end;

procedure TForm1.SetPaintBoxProc( const Value: TProc<TCanvas> );
begin
  FPaintBoxProc := Value;
  if not Assigned( Value ) then
  begin
    PaintBox1.Height := 0;
    PaintBox1.Width := 0;
  end;
  PaintBox1.Invalidate;
end;

end.
Ein kleiner Hinweis sei noch gegeben:
Delphi-Quellcode:
type
  TProcUtil = class
    class function Combine<T>( Collection: TEnumerable < TProc < T >> ): TProc<T>; overload;
    class function Combine<T>( Values: TArray < TProc < T >> ): TProc<T>; overload;
  end;

{ TProcUtil }

class function TProcUtil.Combine<T>( Values: TArray < TProc < T >> ): TProc<T>;
begin
  Result :=
    procedure( Arg: T )
    var
      LProc: TProc<T>;
    begin
      for LProc in Values do
        LProc( Arg );
    end;
end;

class function TProcUtil.Combine<T>( Collection: TEnumerable < TProc < T >> ): TProc<T>;
begin
  Result := Combine<T>( Collection.ToArray );
end;

Dejan Vu 16. Jul 2015 06:49

AW: Suche Konzept: Bild mit unbekannter Größe
 
Entweder Du machst es wie beschrieben, oder Du nimmst Dir ein Bitmap mit maximaler Größe, zeichnest dein Zeugs rein, merkst Dir dabei X/Y Min/Max und blittest (muh? "BitBlt") zum Schluß den Bereich in dein Ziel.


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