vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Top-Preis! AP-Access-Tools-CD Volume 1  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Ein- und Umsteiger
Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Bazi
Datum: 23.12.14 08:45

Hallo, da ich bislang keinen ImageViewer fand der meinen Anforderungen entspricht möchte ich nun versuchen selbst einen zu erstellen.
Nach längerer Suche habe ich den KpImageViewer http://www.codeproject.com/Articles/71225/Image-Viewer-UserControl als Grundlage auserkoren. Den habe ich schon in vb.Net nachgebaut.
Er kann Zoom und Rotation und die nötigen Formate einlesen.

Was mir nun noch fehlt ist das rekonstruierbare Zeichnen darauf. Da fehlen mir auch die Grundlagen in meinem Wissen. Daher nun die ersten Fragen:
1. ist es gut direkt auf der Grafik des Panels zu zeichnen, oder sollte ich besser ein 2.transparentes Panel drüberlegen und darauf zeichnen?

2. Wenn ich zeichne dann speichere ich die Koordinaten der Zeichnungselemente in einer DataTable ab. Da werde ich dann eine Funktion zum umrechnen der Bildpunkte brauchen. Wie berücksichtigt man dabei die Rotation?

Danke für die Hilfe

Gruß Christian

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Manfred X
Datum: 23.12.14 18:04

Hallo!

Ein PictureBox-Control bietet einen festen Hintergrund und
einen Vordergrund zum Zeichnen zusätzlicher (temporärer) Elemente.
Welche Vorgehensweise "gut" ist, hängt von den Details Deiner Zielsetzung ab.

Du speicherst am besten die Bildpunkte in der Basis-Skalierung des
geladenen Image und rotierst das Bild erst nach dem Eintragen Deiner
Elemente per RotateAt-Methode um den gewünschten Mittelpunkt -
die Skalen-Umrechnungen (Rotation, Translation) erledigt dann GDI+.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Franki
Datum: 24.12.14 04:41

Bazi schrieb:
Hallo Christian,

Zitat:

Hallo, da ich bislang keinen ImageViewer fand der meinen
Anforderungen entspricht...


Da scheinen deine Anforderungen zu hoch zu sein bzw. der Betreff falsch gewählt.

Zitat:


Was mir nun noch fehlt ist das rekonstruierbare Zeichnen
darauf. Da fehlen mir auch die Grundlagen in meinem Wissen.
Daher nun die ersten Fragen:
1. ist es gut direkt auf der Grafik des Panels zu zeichnen,
oder sollte ich besser ein 2.transparentes Panel drüberlegen
und darauf zeichnen?


Also es gibt schon durchaus brauchbare Viewer welche diverse Möglichkeiten haben Dateiformate zu wandeln usw. Aber wie der Name schon sagt, sind solche Programme eher für die Ansicht da und nicht um darauf zu zeichnen.

Zitat:


2. Wenn ich zeichne dann speichere ich die Koordinaten der
Zeichnungselemente in einer DataTable ab. Da werde ich dann
eine Funktion zum umrechnen der Bildpunkte brauchen. Wie
berücksichtigt man dabei die Rotation?


Was genau verstehst du denn unter "zeichnen"? Und womit wird durch den User gezeichnet, bzw. was hat der da für Möglichkeiten?

Du sprichst von Koordinaten, das lässt vermuten, dass der User grade Linien zeichnen kann oder Punkte festlegen kann usw. Soweit so gut, das ist zwar möglich, siehe andere Antwort,

aber grundsätzlich solltet man eine Viewer nicht dazu missbrauchen die "gesehenen" Grafiken neu zu zeichnen. Besser ein richtiges Grafikprogramm zu simulieren (wenn man es denn nachprogrammieren möchte) was dann die Ausgangsgrafik nimmt, daran die Veränderungen vornimmt und sie im gleichen Format wieder speichern kann.

Aber so etwas ist nicht trivial, du müsstest genau definieren warum du das selbst machen möchtest und nicht auf eine vorhandene Lösung zurückgreifen kannst. (Es gibt da einige Programme in privaten und gewerblichen Bereich die man per VB/VBA z.B. perfekt steuern kann)
Da lohnt eine Eigententwicklung eigentlich eher nicht.

Wie gesagt, erkläre uns genauer was du da zeichnen möchtest und auch wie das Endergebnis dann aussehen soll wenn die neue Datei geschrieben wird.

Gruß
Frank


Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Bazi
Datum: 24.12.14 12:29

Hallo, danke schon mal voraus für die Antworten.

Was ich machen möchte:
Baupläne von Gebäuden anzeigen, darin Linien einzeichnen und somit Strecken berechnen, Kreise einzeichnen und damit Stückzahlen ermitteln, Polygone einzeichnen und damit Flächen berechnen und auch Hinweistexte einzeichnen.

Die Pläne habe ich als PDF und wandle sie mit PDF2Image in Bilder. Die zeige ich dann im ImageViewer an.
Die Elemente werden alle mit der Maus eingezeichnet. Vorher wird per Button ausgewählt was gezeichnet werden soll, und Farbe und Strichstärke festgelegt.
Die gezeichneten Elemente (Figuren) werden im Dataset mit den Koordinaten im Image abgelegt.
Hier habe ich eine funktionierende Version, allerdings ohne Rotation. Allerdings habe ich bei der den Code großteils nicht selbst geschrieben sondern hatte Hilfe (die mir aber derzeit nicht mehr zur Verfügung steht). Und dummerweise kenne ich mich mit Grafik fast nicht aus.
Die Erklärungen im Objektkatalog (F2) und der MS-Hilfe bringen mich nicht wirklich weiter.

Der Viewer den ich nun nachgebaut habe lädt nicht in eine Picturebox, sondern zeichnet auf ein Panel.
Da bin ich nun unschlüssig ob ich auch darauf zeichnen soll, oder besser noch ein 2.transparentes Panel drüberlege und darauf zeichne. Später soll alles dann zusmmengeführt werden, entweder in einem PDF-Export oder einem Druck.

Wenn ich nun zeichne und eine Rotation von 270° habe, dann muss ich ja die Koordinaten im Image errechnen, und dabei die Rotation berücksichtigen. Dann berechne ich doch anstatt von oben links von unten links?
Die gezeichnete Figur lade ich dann in eine Matrix, rotiere die und speichere dann die Koordinaten im Dataset ab? Und beim verschieben des Bildes muss ich dann alle im sichtbaren Bereich invalidieren und neu zeichnen?

Ach ja, warum ich kein fertiges Produkt nehme? Ich habe mir verschiedene schon gekauft, und dann immer wieder festgestellt dass sie doch irgendwas nicht können.
Ich habe:
Brava-Desktop, der kann alles was ich brauche ist aber vom Lizenzmodell bescheiden.
Von Viscomsoft den cp pro activeX, der kann keine Polygone. Die haben mir zwar zusätzlich ein PaintEvent einprogrammiert das in der Standardversion nicht verfügbar ist, aber ohne Übergebe des Grafikobjektes. Also bin ich damit noch weniger weit als mit dem Viewer den ich nun gebaut habe.
Und ich habe einen PictureViewer mit dem ich in meiner derzeitigen Version arbeite, der auf einem ScrollableControl basiert. Aber der kann keine Rotation und zerstückelt mir das Bild beim drehen des Mausrades.
Deswegen möchte ich nun auf dem nach KpImageViewer nachgebauten aufbauen (oder aufbauen lassen wenn das einer gegen Bezahlung machen möchte).


Danke für die Hilfe

Gruß Christian

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Manfred X
Datum: 24.12.14 21:26

[I]...dummerweise kenne ich mich mit Grafik fast nicht aus.
Die Erklärungen im Objektkatalog (F2) und der MS-Hilfe bringen mich nicht wirklich weiter.[/I]

Tja, was können wir unter diesen Bedingungen im Rahmen des Forums tun ???

Wenn Du mit GDI+ (=Graphics-Objekt) arbeitest, findest Du zahlreiche Beispiele, insbesondere
zur "Manipulation" der Koordinatensysteme, die beim Zeichnen von Elementen jeweils verwendet
werden. Ein Entwicklung eines "anspruchsvollen" Zeichenprogramms setzt gewisse Kenntnisse voraus.

Überblick

Überblick MSDN (Links)

Ausführliches Tutorial

Matrix-Transformationen
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Bazi
Datum: 25.12.14 20:21

Danke für die Links.

Ich habe alles gelesen. Einen Teil davon kannte ich, vieles habe ich dazugelernt, manches auch nicht verstanden (was ich vermutlich eh nicht brauche)
.
Mir ist noch nicht klar wie ich die Koordinaten berechne mit Berücksichtigung der Rotation und was ich in die Matrix lade.

Angenommen ich habe eine Rotation von 270 und einen Point im Steuerelement von 50/50 bei Zoom = 1.
Dann berechne ich die Koordinaten im Image von unten links? Also Breite des Image (weil ja gedreht) - 50 / 50 ?

In die Matrix werden die Koordinaten eines Elementes geladen, das ich anzeigen möchte? z.B. eine Linie aus der DataTable. Die kann ich dann entsprechend den Anforderungen Transformieren, Rotieren... und dann zeichnen?

Danke für die Hilfe

Gruß Christian

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Manfred X
Datum: 29.12.14 08:40

Vielleicht hilft dieser Code zum Verständnis -
(eine Modifikation dieses Beispiels)

 
''' <summary>Linie unter Einbezug einer Rotation zeichnen</summary>
''' <param name="gr">Graphics-Objekt für die Zeichnung</param>
''' <param name="line_start">Punkt definiert den Beginn der Linie (ohne 
' Rotation)</param>
''' <param name="line_end">Punkt definiert das Ende der Linie (ohne 
' Rotation)</param>
''' <param name="line_color">Farbe der Linie</param>
''' <param name="line_width">Breite der Linie</param>
''' <param name="rotation_center">Zentrum der Rotation (bei 0/0 Mitte der 
' Linie)</param>
''' <param name="line_angle">Drehwinkel im Uhrzeigersinn (in Grad)</param>
Private Sub DrawLine(gr As Graphics, line_start As Point, line_end As Point, _
                     ByVal line_color As Color, _
            Optional ByVal line_width As Integer = 1, _
            Optional ByVal rotation_center As Point = Nothing, _
            Optional ByVal line_angle As Double = 0)
 
        Using path As New System.Drawing.Drawing2D.GraphicsPath, _
            rotatematrix As New Drawing2D.Matrix, _
            line_pen As New Pen(line_color, line_width)
 
            path.AddLine(line_start, line_end)
 
            If rotation_center = Nothing Then
                rotation_center.X = _
                     line_start.X + (line_end.X - line_start.X) \ 2
                rotation_center.Y = _
                     line_start.Y + (line_end.Y - line_start.Y) \ 2
            End If
 
            rotatematrix.RotateAt(CSng(line_angle), rotation_center)
            path.Transform(rotatematrix)
            gr.DrawPath(line_pen, path)
        End Using
    End Sub
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Bazi
Datum: 03.01.15 19:36

Danke Manfred,

das hat mir weiter geholfen.

Insgesamt habe ich den Viewer nun funktionsfähig. Ich konnte eine Funktion integrieren die mir die Position im Image zurückgibt, bei übergebenem Point im Viewer.

Offen ist noch die Frage wo ich besser zeichnen sollte.
Ein Image wird beim Öffnen auf ein Panel gezeichnet und angezeigt.

Wenn ich nun bspw. eine Linie darüber zeichne und diese wieder löschen möchte (warum auch immer), dann müsste ich die gesamte Zeichnung neu laden? Dann wäre es wohl besser meine Figuren auf ein 2.Panel zu zeichnen, das darüber liegt? Somit erspare ich mir das Restaurieren.
Im Falle eines Export oder Druckes müsste ich halt dann beide zusammenführen.

Wie handhabt Ihr sowas?

Gruß Christian

Danke für die Hilfe

Gruß Christian

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Bazi
Datum: 03.01.15 22:48

noch weitere Fragen:
Wenn ich den Viewer als .dll in ein Projekt einbinde und dann darauf zeichnen möchte,
dann zeichne ich ja gar nicht wie ich erst dachte auf dem Panel, sondern müsste in dem Fall ja eigentlich auf dem Hauptform meines Viewers zeichnen?
Weil an das Paint-Event des Panels komm ich ja gar nicht ran. Das Paint das ich bekomme ist ja das vom Formular. Richtig? Dann muss ich da ggf. nochmals die Koordinaten umrechnen?

Gruß Christian

Danke für die Hilfe

Gruß Christian

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Manfred X
Datum: 04.01.15 22:06

Wenn Du auf einem Formular ein Panel-Control hast, auf dessen
Oberfläche gezeichnet werden soll, mußt Du das Paint-Event dieses
Panels verarbeiten - nicht das der Form.

Die Event-Verarbeitungsroutine (z.B. "Handles Panel1.Paint") wird im Formular
vereinbart. Sie erhält als zweiten Parameter eine Instanz der
PaintEventArgs-Klasse. Dort findet sich als schreibgeschützte Eigenschaft
("e.graphics") eine Referenz auf eine Instanz des Graphics-Objekts, die bereits
eingerichtet ist, um auf dem Panel zu zeichnen (Koordinaten etc).

Wie in der Routine "DrawLine" (auch MSDN) gezeigt, kannst Du dieses
Graphics-Objekt an eine Zeichnungs-Routine als Parameter übergeben.
Diese Routine kann auch in einer Bibliothek deklariert sein.

Warum Du die Umrechnung der Koordinaten selbst erledigen willst,
verstehe ich nicht. Das ist nicht erforderlich, weil GDI+ die
Verschiebung/Rotation/Skalierung des jeweils beim Zeichnen zu
verwendenden Koordinatensystems ermöglicht.

Falls Du die Rotation in der Fläche selbst berechnen willst,
verwende eine 2D-Rotationsmatrix und multipliziere damit die X-/Y-Koordinaten.









Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Bazi
Datum: 05.01.15 15:03

Hallo Manfred,

vieleicht denke ich auch nur zu kompliziert.
Manfred X schrieb:
Zitat:


Warum Du die Umrechnung der Koordinaten selbst erledigen
willst,
verstehe ich nicht. Das ist nicht erforderlich, weil GDI+ die
Verschiebung/Rotation/Skalierung des jeweils beim Zeichnen zu
verwendenden Koordinatensystems ermöglicht.


Beispiel:
Ich möchte eine Linie zeichnen. Beginn der Linie ist MouseDown, Ende der Linie die aktuelle Mausposition. Beim verschieben der Maus soll sich die Linie entsprechend verändern.

Beim MouseDown erzeuge ich einen Datensatz in meiner Tabelle "Figuren", der für diese Linie steht. In einer Tabelle "Points" speichere ich die Punkte dazu. Beim Erzeugen also erstmal 2 identische Points. Beim verarbeiten des MouseMove wird der 2.Point dieser Linie auf die aktuelle Position gesetzt.

Das ganze funktioniert ja nur mit Koordinaten im Image, da sich die des Viewers ja je nach Ausschnitt und Zoomfaktor verändern.
Ich habe nun eine Funktion PointToImage geschrieben, die mir den jeweiligen Point im Image zurückgibt, der dann in der Tabelle gespeichert wird.
Wenn ich aber nun die Linie auf mein Panel zeichnen möchte muss ich doch wieder die Points im Viewer berechnen, an denen gezeichnet werden soll, oder? Die sind ja je nach Zoomfaktor wieder anders.
Die Linien müssen auch beim schließen bzw. neu öffnen des Programmes wieder gezeichnet werden.

Oder gibt es da was einfacheres?
Im fertigen Programm sollen Linien, Rechtecke, Ellipsen, Kreise, Polygone und Text gezeichnet werden.

Das Zeichnen der Figuren ist an sich nicht das Problem, eben nur die Umrechnung damit sie an der richtigen Stelle erscheinen.

Gruß Christian

Danke für die Hilfe

Gruß Christian

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Manfred X
Datum: 05.01.15 18:33

Ich würde vorschlagen, du läßt den Nutzer zunächst per Maus die Position einer
Linie festlegen. Sobald (z.B. im MouseUp) die Definition der Linie durch den
User abgeschlossen ist, werden die Mauskoordinaten unter Zugrundelegung des aktuellen
Zoomfaktors auf Koordinaten im Originalbild zurückgerechnet (jeweils Längen- und Breitenfaktor
gemäß den relationen der Original-/Anzeige-Abmessungen).
Diese Koordinaten werden gespeichert.

Für Anzeige wird das Bild zunächst in eine Bitmap geladen (Originalgröße)
und die gespeicherten Figur-Koordinaten werden in dieser Bitmap eingezeichnet (Graphics-Objekt).
Umrechnungen sind dabei nicht erforderlich.
Die mit den Figuren versehene Bitmap kann dann in einen Viewer geladen werden - eventuell unter
Anwendung der FlipRotate-Methoden.



Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Bazi
Datum: 05.01.15 19:51

Das kann ich vom Workflow her nicht so machen.
Ich lade ein Bild als Hintergrund. Darüber zeichne ich dann verschiedene Figuren, die ich im DataSet speichere. Die Länge einer Linie muss bereits beim Zeichnen sichtbar sein, da sich diese an der Hintergrundgrafik orientieren.
Beim erneuten Laden des gleichen Bildes werden diese dann auch wieder eingelesen und angezeigt.
Der Benutzer muss aber jederzeit wieder neue einzeichnen und bestehende bearbeiten / löschen können.

Daher der Weg jede Figur einzeln zu zeichnen. Das können schon mal um die 100 Stück sein.

Wenn der Anwender dann die Zeichnung dreht, muss ich auch alle gezeichneten Figuren mitdrehen.

Gruß Christian

Danke für die Hilfe

Gruß Christian

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Manfred X
Datum: 06.01.15 09:58

Selbstverständlich mußt Du in Deiner Datenbank das Originalbild und
die Koordinaten der zugehörigen Zeichnungselemente bezogen auf
die Positionen im Originalbild speichern.

Wenn diese Elemente frei editierbar sein sollen, kannst Du keinen
einfachen "Viewer" verwenden, sondern mußt einen für Deine Zwecke
geeigneten Editor für Diagramm-Elemente einsetzen.
Gezoomte, partielle und rotierte Darstellungen der Diagrammdaten
beim Editieren durch den Benutzer, muß dieser Editor beherrschen
(Re-Skalierungen).
Dem Editor werden die Bilddaten aus der Datenbank übergeben
dort für den User entsprechend aufbereitet und nach dem Editieren die
Liste der modifizierten Elemente zurückgegeben.

Falls Du so etwas selbst programmieren willst, hängt das geeignete
Vorgehen z.B. stark vom Aufbau und der Bedienung der Benutzer-Oberfläche
ab, aber auch davon, wie die Elemente in der Fläche angeordnet werden
können (Überschneidungen, Kombinationen, Darstellungsebenen usw.)
und wie Elemente vom Benutzer bearbeitet werden können
(z.B. Verschiebung oder Löschung ganzer Bildbereiche, der einzelnen
Figur als Ganzes, einzelner Punkte innerhalb eines Elements).
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Erstellen eines ImageViewers - grundlegende Fragen 
Autor: Bazi
Datum: 06.01.15 12:18

Hm, eigentlich bräuchte ich wohl nen CAD-Editor. Da habe ich allerdings nichts für mich erschwingliches gefunden. Ich dachte da ich nur einfache geometrische Figuren habe könnte ich das auf Basis eines Viewers (der inzwischen auch funktioniert) selber bauen und bei Bedarf um weitere Möglichkeiten ergänzen.
Das Thema ImageViewer ist somit erledigt, für weiterführende Fragen zum Editor mache ich dann einen eigenen Thread auf.
Danke für die Hilfe.
Christian

Danke für die Hilfe

Gruß Christian

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel