Hallo,
Da ich in meinem letzten Thread einige Tipps + Tricks zum Thema Bildverarbeitung bekommen habe, sitz ich nun hier und würde generell wissen, welche Schnittstelle ihr mir raten würdet wenn ich:
benötige ?
Bisher läuft alles über DirectShow.NET und ich hol mir über das ISampleGrabberCB Interface den aktuellen Frame des AVIs und stell's in einer Picturebox dar. Jedoch lagt das nach einer Zeit extrem und führt manchmal zum kompletten Stillstand. Jetzt ist schon ein Buffer gebastelt worden, der 5 Bilder im voraus speichert, aber das ist auch eher "Notgedrungen" und nicht gerade sauber.
Wie würdet ihr das angehen ? Ich hätte z.b. die Idee, das AVI direkt mit DirectShow anzeigen zu lassen, aber bisher stoße ich auf das Problem, dass DirectShow das Fenster, in dem ich es zeichne, komplett überschreibt und keine eigenen Objekte zulässt.
Vielen Dank für jede Hilfe !
lg
Phil
Hallo,
Ich habe nun herausgefunden, warum es manchmal hängt:
Das Bitmap, welches ich zum zeichnen verwende, wird über eine managed DirectX Methode aus einem AVI-Film gelesen (war nicht anders möglich) und dann über diese Schnittstelle ausgelesen.
Jetzt kann es aber manchmal sein, dass beim schnellen Scrollen das Image gerade gezeichnet wird, jedoch die API noch beim auslesen des Bitmaps aus dem AVI Film ist. Sprich sie greifen auf den gleichen Speicher zu.
Du hast recht mit deiner Vermutung, dass das _bitmap Array ein Bitmap Buffer ist (hat damals vor paar Jahre ein Kollege programmiert, den hab ich erst jetzt fragen können), damit man diesem Problem Herr wird. 100% funktionieren tut's aber nicht.
Meine weitere Frage zu dem Thema:
Gibt es eine Möglichkeit, den Image-Speicher bei schnellem Scrollen synchron zu halten?
Vielen Dank für die Inputs soweit
@Picturebox. Mittlerweile bin ich soweit, dass ich die Picturebox vererbe und in der vererbten Klasse das Bild direkt mit pe.Graphics.DrawImage() zeichne .. Ist das schneller? Oder gibt's da noch schnellere Möglichkeiten (native ? )
lg
Philipp
Puh,
Das ist ja mal eine gute Optimierung.
@1. OK das ist klar. Ehrlich gesagt war mit nicht bewusst, dass das direkte Casten große Probleme machen kann
@2. Wow .. OK SO genau wusste ich's dann auch nicht.
Aber es ging mit deinem Code gut (außer dass input + output vertauscht war)
Die Strides sind gleich groß, also konnte ich den Wert von data.Stride auch für den Output übernehmen.
Dein Code ist nochmal um ein Stück schneller als bisher ..
Das schlimmste ist jetzt das hochzählen von "y" in der for Schleife .. Wahnsinn ^^ .. Danke!
Da du dich scheinbar echt gut auskennst noch eine Frage, die du zufällig wissen könntest:
Im Prinzip lese ich ein Video aus und stelle aus zwei verschiedenen AVI-Streams die jeweiligen Bilder in einer Picturebox dar. Ab und zu bleibt das Bild einfach hängen beim schnellen durch-scrollen und ich brauch ca. 5Sekunden bis zu 1 Minute damit das Programm wieder reagiert ... Kann es da zu einem Memoryproblem kommen ?
Der gesamte Quelltext der Funktion sieht jetzt so aus, vllt kannst du das aus dem Quelltext heraus erkennen..
Vielen Dank auf jeden Fall !!! 😃
int ISampleGrabberCB.BufferCB(double sampleTime, IntPtr pBuffer, int bufferLen)
{
Bitmap bitmap = _bitmaps[(_currentBitmap + 1)%NUM_BITMAPS];
if (bitmap == null || bitmap.Height != VideoHeight || bitmap.Width != VideoWidth)
{
_bitmaps[(_currentBitmap + 1)%NUM_BITMAPS] = new Bitmap(VideoWidth, VideoHeight,
PixelFormat.Format24bppRgb);
bitmap = _bitmaps[(_currentBitmap + 1)%NUM_BITMAPS];
}
if (bufferLen == bitmap.Width * bitmap.Height * 3)
{
var r = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData data = bitmap.LockBits(r, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
int inputStride = data.Stride;
int outputStride = data.Stride;
int bytesPerLine = VideoWidth*3;
for (int y = 0; y < VideoHeight; y++)
{
int reverseY = (VideoHeight - 1) - y;
IntPtr inputLine = pBuffer + (reverseY*inputStride);
IntPtr outputLine = data.Scan0 + (y*outputStride);
RtlMoveMemory(outputLine, inputLine, bytesPerLine);
}
bitmap.UnlockBits(data);
_currentBitmap++;
Changed(this, null);
}
return 0;
}
lg
Phil
Ha du bist gut .. Darauf hätte ich auch selber kommen können aufKopfklatsch
Von 33% auf 14,8% runter .. Danke dir =)
Sieht jetzt so aus:
unsafe
{
int stride = m_videoWidth * 3;
//RtlMoveMemory(data.Scan0, pBuffer, stride);
byte* dst = (byte*)data.Scan0.ToPointer();
byte* src = (byte*)pBuffer.ToPointer();
for (int i = 0; i < this.m_videoHeight; i++)
{
byte* str = src + (this.m_videoHeight - i - 1) * stride;
RtlMoveMemory((IntPtr)dst, (IntPtr)str, stride);
dst += stride;
}
}
Danke nochmals
lg
Phil
Liebe MyCshapr Community,
Ich bin beim Performance testen auf folgende Schwachstelle in meinem Programmcode gekommen
unsafe
{
int stride = m_videoWidth * 3;
//RtlMoveMemory(data.Scan0, pBuffer, stride);
byte* dst = (byte*)data.Scan0.ToPointer();
byte* src = (byte*)pBuffer.ToPointer();
for (int i = 0; i < this.m_videoHeight; i++)
{
byte* str = src + (this.m_videoHeight - i - 1) * stride;
for (int j = 0; j < stride; j++)
{
*(dst++) = *(str++);
}
}
}
Hat wer von euch eine Idee, wie ich diesen Codeblock beschleunigen könnte?
Im Speziellen verursacht "*(dst++) = *(str++)" den Performanceverlust (Laut Visual Studio bis zu 33% Programmweit O_O)
Vielen Dank
lg
Philipp
Na gut, ich schein glaub ich zu viel um den heißen Brei rumzureden.
Ich such seit Tage schon nach einer ausführlichen Beschreibung der Vector3D und Matrix3D Klassen, uzw. nicht nur "M12 is first row, second column" sondern auch deren Bedeutungen usw. Ich dachte, daß ich das hier mal frage und wollte mit dem Beispiel gleich erklären warum ich das suche. Einfach weil beim AutoCAD und beim WPF nicht die gleichen Ergebenise rauskommen. Das Koordinatensystem ist bei beiden gleich, was ich bisher feststellen konnte.
Den Auszug mit dem "Fehler" war jetzt nicht gemeint, daß es darum geht, sondern galt als Hintergrund warum ich überhaupt das Ganze mache. (Quasi als Einleitung des restlichen Codes, den ich zuletzt gepostet habe)
Einzelschrittdebugging verwende ich schon. Ich hänge halt, wie gesagt, schon bei der ersten Rotation, die mir nicht das gleiche auswirft. Bzw. ich nicht weiß, ob die Matrix Rotation z.b. das Quadrantenproblem schon ausmerzt oder in welche Richtung ich drehe wenn ich positiv drehe. Bei der Methode steht "Appends a rotation transform to the current Matrix3D. " und das war's .. Kein Beispiel, keine Zeichnung wie man sich das vorstellen kann oder so. Klar normalerweise braucht man so etwas auch nicht, weil's ja, wie du richtig festgestellt hast, es schon implementiert ist und man es einfach nur verwenden muss. .. Aber gerade bei solchen Funktionen wäre es wichtig zu wissen, was für mathematische Operationen da im Hintergrund ablaufen, um den Input anzupassen
mhmm .. und was ich letztendlich suche ist z.b. ein Beispiel oder eine Referenz, das mir eine saubere Transformationsimplementierung beschreibt anhand der ich debuggen kann. (Aber nicht in 2D, da gibt's genug, das stimmt 😃 )
lg
Phil
Mhmm .. OK so wie du klingst schein ich einen völlig falschen Ansatz zu verfolgen kopfkratz
Ich meinte nicht die Rotation an sich als quellcode, sondern wie man sich das vorstellen kann, in welche Richtung es dreht etc.
Anders gefragt... Was würdest du für so eine Transformation verwenden ? Scheinbar nicht die PresentationBase vom WPF ..
Es ist im Moment so, daß wir diese Transformation über eine lange Funktion mit diversen mathematischen Operationen realisiert haben. So jetzt ist da nur irgendwo ein kleiner Fehler drinnen und wie so oft typisch, gibt es den Typen nicht mehr, der diesen Code geschrieben hat. So und meine Aufgabe wäre jetzt, das ganze nachzuvollziehen (ok das geht noch) und einfacher zu programmieren, damit es leichter verwaltbar wird.
Ich dachte mir an sowas z.b.:
// Relativer Vektor von der Kamera zum Objekt
Point3D point = new Point3D(1.257, -0.875, -11.379);
Point3D output;
Matrix3D resFromDll = Matrix3D.Identity;
// Verdrehung der Kamerawinkel zur IMU einrechnen
resFromDll.Rotate(new Quaternion(new Vector3D(1, 0, 0), 90 - (11 + 0.502)));
resFromDll.Rotate(new Quaternion(new Vector3D(0, 0, 1), -10));
// Kameraoffsets zur IMU
resFromDll.Translate(new Vector3D(-1.236, 0.121, 2.406));
// Verdrehungen nach pitch/nick
resFromDll.Rotate(new Quaternion(new Vector3D(0, 1, 0), -2.133));
resFromDll.Rotate(new Quaternion(new Vector3D(1, 0, 0), -0.502));
// Verdrehung heading
resFromDll.Rotate(new Quaternion(new Vector3D(0, 0, 1), 180 + 95.323));
// Absolute Koordinaten einbeziehen
resFromDll.Translate(new Vector3D(7180.147, 347923.101, 161.904));
output = point*resFromDll;
Das wär der aktuelle Quellcode, der aber nicht genau (paar meter daneben) zum gewünschten Ergebnis kommt (ok das will ich jetzt auch net erfragen, aber wollte eben wissen ob solche Beispiele mit der PresentationCore überhaupt sinnvoll sind ..) ..
Hmm .. Im Prinzip ja, sry dass ich dich damit verwirrt habe, ich dachte nur ich erzähl von dem Einsatzzweck damit klar ist, was ich machen will..
Wenn man's genau nimmt ist es aber so, dass die absolute Koordinate in der IMU, also im Fahrzeuginneren gespeichert ist. D.h. ich muss den Vektor vom Kamerastandort aus in die IMU transformieren und dort dann mit der absoluten Koordinate verknüpfen.
Mein Grundlegendes Problem ist aber immer noch, dass egal in welchem Quadranten ich die Rotation durchführe, ich nie zum gleichen Ergebnis komme wie mit AutoCAD.
Gibt es für die Matrix3D Klasse eine vernünftige Anleitung, was genau bei der Rotation passiert? Klar ich kann im dissasembler nachschauen welche Zellen multipliziert werden, aber ich bin, wie man sicher schon gemerkt hat 😉, kein Mathematiker und kann mir das Modell visuell zwar herleiten, aber sollte es mit einer vernünftigen Matrix abbilden
Vielen Dank für deine Hilfe soweit 😃
lg
OK, sry .. ich versuch's noch mal weniger wirr zu schreiben ^^
Also gegeben ist ein Stereokamerasystem.. Die Parameter besitze ich alle um erfolgreich transformieren zu können (also die Verdrehungen und Transformationen). Und aus dem System messe ich einen relativen Vektor zu einem Objekt.
Achja und ich meine nicht den Algorithmus zur Bestimmung des relativen Vektors aus dem Bild heraus, sondern dieser Vektor ist schon vorhanden, er muß "lediglich" in absolute Weltkoordinaen gebracht werden.
Und die Aufgabe meines Systems wäre die transformation des relativen Vektors zu einer absoluten Koordinate. Wie gesagt die Angaben hab ich alle dafür.
Um zu verdeutlichen, was ich meinte, hab ich im AutoCAD einen Block gezeichnet mit den Maßen 1 / 1 / 1, was einem Vektor 1 / 1 / 1 entspricht. Diesen Block hab ich um die X und dann um die Z Achse um je 10° gedreht und erhalte die oben genannten Werte für die Diagonale des Blocks (also quasi als ob ich den Vektor gedreht hätte) --> 0,8112 / 1,3145 / 0,78636
Das wollte ich 1:1 mittels Matrix3D abbilden, aber irgendwie komm ich nicht auf das gleiche Ergebnis. Ich hab mir schon gedacht, dass es vllt an einem Quadrantenproblem liegt und hab alle Möglichkeiten probiert. Also von 90, 180 und 270 jeweils die 10° dazu oder abgezogen. Das "beste" Ergebnis ist immer noch wenn ich 180 - 10° verwende, nur dann ist x und z gespiegelt negativ --> -0,78636 / 1,3145 / -0,8112
Gibt es für Matrix3D vllt irgendeine genauere Beschreibung außer der MSDN ?
Vielen Dank auf jeden fall schon mal für die Identity Matrix und dem Tipp für die Matrixmultiplikation. Manchmal denk ich einfach zu kompliziert ..
lg
[EDIT]
Wenn ich eine Translation in der Matrix ausführe und nacher den Vektor mit der Matrize multipliziere, wird die Translation nicht berücksichtigt 😦 .. Darum hab ich diesen MatrixTransform3D verwendet .. Warum verwendet der *-operator keine Translation ? Hab per reflector nachgeguckt, er leitet es quasi an die Transform Methode der Matrix3D weiter und die macht einfach keine Translation
Hallo MyCSharp Team,
Zur Zeit arbeite ich mit der Matrix3D und Vector3D Klasse der PresentationCore Library.
Mein Ziel ist eine "echte" Affine Transformation, in der ich auf Basis von relativen Vektoren absolute Koordinaten berechne, indem ich eben die Koordinaten transformiere.
Jetzt ist es aber so, daß ich einfach nicht auf die gleichen Werte wie meine Excel Berechnungen komme. Als Validierung verwende ich AutoCAD. Wenn ich im AutoCAD eine Drehung ausführe, und sie mithilfe der "Rotate" Funktion von Matrix3D nachmache, ist der resultierte Vektor nicht identisch.
Verwende ich die Matrix3D Klasse falsch oder was für Tipps habt ihr für den Umgang damit?
[Edit] Als Beispiel:
Im AutoCAD einen Block, mit
1 / 1 / 1
gezeichnet und ihn nach X um 10° und nach Z um 10° gedreht ergibt:
0,8112 / 1,3145 / 0,78636
In C# hab ich adäquat folgendes versucht:
Matrix3D testMatrix = new Matrix3D();
testMatrix.Rotate(new Quaternion(new Vector3D(1, 0, 0), 10));
testMatrix.Rotate(new Quaternion(new Vector3D(0, 0, 1), 10));
Point3D inputPoint = new Point3D(1, 1, 1);
Point3D outputPoint = new Point3D();
MatrixTransform3D outputTest = new MatrixTransform3D();
outputTest.Matrix = testMatrix;
outputTest.TryTransform(inputPoint, out outputPoint);
Das Ergebnis ist:
0,84395 / 0,97248 / 1,158455
[/Edit]
Vielen Dank
[Edit2]
Oder weiß vllt jemand eine bessere Lösung. Meine grundlegende Aufgabe:
Gegeben ist ein relativer Vektor eines Stereokamerasystems und dieser Vektor muss zum Fixpunkt des Wagens gebracht werden und dann in das Weltkoordinatensystem. Klingt einfach, ist aber aufgrund der verschiedenen Verdrehungen (roll / pitch / heading) nicht so einfach ..
[/Edit2]
lg
Phil
oh .. danke dir !
Oh mann wie peinlich .. ja du hast recht ! .. vielen dank! .. Hab schon alles umgeschrieben und anders verschachtelt .. aber so "einfache" dinge hab ich depp net geachtet ..
.. D.h. performance geht runter wenn ich an einem String was drann hänge laufend?
Hallo,
Da ich leider gerade nicht weiter weiß, wende ich mich an die Community.
Folgender Code funktioniert bei einem Textfile mit 273kb perfekt, bei 5,8MB wird er EXTREM träge und langsam:
using (FileStream mReadStream = new FileStream(file, FileMode.Open, FileAccess.Read))
{
using (StreamReader mStreamReader = new StreamReader(mReadStream))
{
using (FileStream mWriteStream = new FileStream(file.Replace(".txt", "_premup.txt"), FileMode.Create, FileAccess.Write))
{
using (StreamWriter mStreamWriter = new StreamWriter(mWriteStream))
{
string CurrZeile;
string[] CurrStrings;
char[] splitChar = new char[] { '\t' };
decimal CurrValue;
decimal LastIntervall = 0;
decimal CurrDelta = 0;
decimal LastDelta = 0;
int CurrFrame = 0;
int LastFrame = 0;
string LastString = "";
bool negativDiff = false;
/*
* Group5+6: Steuerzeichen -> GPS-Zeit -> Weg -> ID
*/
while (!mStreamReader.EndOfStream)
{
CurrZeile = mStreamReader.ReadLine();
CurrStrings = CurrZeile.Split(splitChar);
if (CurrStrings.Length < 4)
break;
if (!decimal.TryParse(CurrStrings[2], out CurrValue) || !Int32.TryParse(CurrStrings[3], out CurrFrame))
{
m_error += "\r\nWrong File Format!";
return false;
}
if ((LastFrame != 0 && CurrFrame != 0) && (CurrFrame - LastFrame != 1))
{
m_error += "\r\n" + file.ToString() + ": Event-IDs nicht konstant steigend!";
return false;
}
CurrDelta = CurrValue - LastIntervall;
if (CurrDelta < 0 && !negativDiff)
{
m_error += "\r\n" + file.ToString() + ": Event mit ID " + CurrStrings[3] + " hat eine negative Differenz!";
negativDiff = true;
if (!deletenegativDiff)
{
mStreamWriter.WriteLine(LastString);
countdata++;
continue;
}
}
if (!deletenegativDiff && negativDiff)
{
mStreamWriter.WriteLine(LastString);
countdata++;
negativDiff = false;
}
else if (LastIntervall == 0)
{
CurrDelta = 2;
}
else if ((CurrDelta + LastDelta) > maxdelta)
{
mStreamWriter.WriteLine(LastString);
countdata++;
}
else
{
m_error += "\r\n" + file.ToString() + " Event mit ID " + LastString.Split(splitChar)[3] + " gelöscht!";
m_sumDelted++;
CurrDelta += LastDelta;
}
LastString = CurrZeile;
LastDelta = CurrDelta;
LastIntervall = CurrValue;
}
mStreamWriter.WriteLine(LastString);
}
}
}
}
Ich versteh nur nicht, warum bei einer 273 kb datei das ganze ms dauert, und bei 5,8MB ewig braucht ..
Vielen dank für jede Hilfe
lg
PhilHol
Hallo.
Ich hab leider XML erst begonnen und wollt das sauber auf dem XML namespace aufsetzen ..
sprich mit complex + simpletypes .. usw. ..
hab deinen code iE auch schon gemacht aber dann lässt er mich, logischerweise, das XML nicht mehr nach dem schema validieren ..
Hallo
benötige das relativ dringend für die Arbeit 😕 ..
Hat keiner eine Idee ? .. Irgendwie denk ich scheinbar zu komplex ..
verwendetes Datenbanksystem: XML
Hallo,
Ich hab ein Programm geschrieben, dass mit den UserProperties alle Konfigurationen speichert.
Nun wächst aber diese Konfiguration mir schon langsam über dem Kopf (20 verschiedene Properties und darin enthalten mit komma, querstrich, rufzeichen ... serialisierte Daten)
Darum habe ich beschlossen, das alles sauber in XML abzubilden.
Soweit so gut.
Nur leider stehe ich vor einem, wahrscheinlicher beginner-, Problem
Nehmen wir folgendes an: Ich habe mehrere Skalentypen .. (skala a, skala b, skala c) und diese Skalen enthalten natürlich vorschriften (<1° -> rot, <2° -> blau, <3° -> grün)
d.h. struktur sieht folgendermaßen aus:
|- skala a
| |- <1° -> rot
| |- <2° -> blau
| |- ....
|- skala b
| |- <2,3° -> gelb
...
usw.
Das is aber nur eine art "auswahl" für ein Element des eigentlichen XMLs ..
<xs:element name="Skala" type="SkalaType">
wobei Skalatype als auswahl "skala a", "skala b" haben soll mit allen infos dahinter
Wie bilde ich das sauber ab in XML ?
Danke für jeden Hinweis 🙂
lg
Hab ich das richtig verstanden .. du willst mittels C# die mssql datenbank installieren ?
wenn ja :
http://msdn.microsoft.com/de-de/library/bb264562.aspx
lg 🙂
Hallo,
Du deklarierst myProxy als WebProxy und nicht als IWebProxy in Zeile 2.
Darum castest du falsch in Zeile 3.
Aber myWebRequest.Proxy liefert tatsächlich einen IWebProxy zurück, darum castest du besser auf WebProxy (wenn das geht)
Dann müsste reichen :
HttpWebRequest myWebRequest = (HttpWebRequest)WebRequest.Create("http://www.microsoft.com");
WebProxy myProxy = (WebProxy)myWebRequest.Proxy;
MessageBox.Show(myProxy.Address.ToString());
ah stimmt ... cool danke .. hab ich echt net gefunden Oo .. ja auch suchen will gelernt sein -.-
naja .. für alle die danach suchen (in vb.net - in c# gibts das sicher auch aber mir reicht die info wie's geht 😉)
http://www.codeproject.com/KB/vb/SQL_Connection_Dialog.aspx
lg 🙂
[edit]dank dem .net reflector weiß ich nun wie der dialog die server infos bekommt:
System.Data.Sql.SqlDataSourceEnumerator ist das stichwort 🙂
Hallo,
Ich würde gerne die Auswahl des Add Connection Dialogs bei Visual Studio 2008 nachbauen.
VS 2008 scheint es ja zu schaffen, dass er alle datenbanken in seiner umgebung findet. Wie macht es das ?
Ich hab im Forum schon ein bischen gesucht und hab es grad mal geschafft (durch eine gefundene Klasse) die Namen aller Computernamen im netzwerk auszulesen.
Weiß wer wie man da nun ein bischen "tiefer" geht.
wollte über DNS.GetHostEntry(); die IP Adressen der host namen bekommen, aber ausser beim lokalen namen wirft er immer eine invalidhost exception.
Hab auch schon probiert einfach vorhandene IP Adressen herzunehmen und mit TCPClient Connect() auf Port 1433 connecten zu versuchen (geht niergends -.- .. komischerweise)
Es gibt auch eine Services Klasse, wo man die Services auslesen kann (aber das geht auch nur bei der lokalen maschine ..)
Naja .. vielleicht kann mir wer helfen 🙁 ..
Hallo,
Mhm .. ja das habe ich eigentlich alles implementiert (so ziemlich)
Aber soweit ich mitbekommen habe, liegt das eher an der fülle von den Controls
Als Beispiel ..
Das heißt der Bildschirm zeigt an:
Form
Kann man das vllt bissl besser gestalten? (hoffe man versteht was ich meine)
Ist eher eine Design frage des Programms ich weiß .. aber ich steh irgendwie an und hab scho gegoogelt + auch CodeProject scho bissl danach gefragt, aber für solche Fälle gibts irgendwie keine Ideen (oder macht man das nicht so ?)
Hallo,
Danke für die rasche Antwort !
Ich bin nun selber draugekommen (wie peinlich)
Die bilder die ich probiert habe, sind wohl durch zu oft durchgeführte manipulation von C# kaputt gegangen -> Darum hat's c# immer geworfen
Danke aber für die links werd das trotzdem mal durchlesen und schauen was ich daraus brauche 🙂
lg
Hallo,
ich hab folgenden code (vollständig!)
using System;
using System.IO;
using System.Drawing;
namespace PDFTester
{
class Program
{
static void Main(string[] args)
{
using (Image img = Image.FromFile(@"1.bmp"))
{
img.Save(@"2.bmp");
}
}
}
}
und bekomme immer eine OutOfMemory Exception beim Einlesen von einem 2,5MB Bild
Kann man größere bilder anders einlesen oder gibts eine methode wie man größere bilder einlesen kann ?
Hallo,
will nicht klguscheissen, aber du verwendest in dem von mir zitierten Beispiel die List<string> lst in der for schleife .. und die hat kein Item prop ..
und bei AddRange(lst) kommt immer:
Argument '1': cannot convert from 'System.Collections.Generic.List<string>' to 'object[]'
AddRange() hat 2 Überladungen: object[] und ListBox.ObjectCollection
lg
Hallo,
Ich hab nach dieser Anleitung:
http://www.codeproject.com/KB/cs/pluginsincsharp.aspx
Ein Modulares Projekt gestartet.
Nun meine Idee war folgendermaßen:
Ich hab ein Form, und dieses Form hat ein PluginHost, der die Plugins verwaltet und schnittstellen bietet -> z.b. LoadModule();
bei LoadModule wird ein UserControl als Argument übergeben, und die Klasse PluginHost schreibt sie dann immer in das Formular.
Vorher wird über eine Schleife kurz geprüft ob andre Module noch was nachändern wollen..
Das funktioniert ganz passabel, jedoch hab ich 1 Problem
Beim Resize, oder allgemein beim verändern der Größe + Position der Formulars kommt es zu furchtbaren Verzögerungen (OK furchtbar .. aber es ruckelt ordentlich)
Hat wer eine Ahnung woran das liegen könnte ? oder womit ich das wegbekomem?
Liegt das am UserControl im Formular ?
Gibts es für sowas optimierte lösungen (modulare systeme) ?
Achja DoubleBufferd = true ist an .. Damits net flackert ^^
Wie gesagt .. jedes modul zeichnet seinen eigenen inhalt hinein, aber kann von andren modulen "erweitert" werden
danke für jede Info 🙂
lg
Hallo,
hab mich gerade bisschen mit Optimierung beschäftigt und, glaube, bin auf einem Fehler bei dir draufgekommen:
Noch schneller geht es übrigens, wenn man die Items.AddRange Methode verwendet.
Auch hier ein kurzes Beispiel:List<string> lst = new List<string>(); for (int i = 0; i < 10000; i++) lst.Items.Add(Item " + i); this.listBox1.Items.AddRange(lst);
Sollte das net so sein
List<string> lst = new List<string>();
for (int i = 0; i < 10000; i++)
lst.Add(Item " + i);
this.listBox1.Items.AddRange(lst.ToArray());
? Weil dein Beispiel geht so nicht ^^ (finde kein Item Propertie in einer List und keine möglichkeit AddRange mit einer List standardmäßig zu befüllen)
Lg
um meine frage selber zu beantworten:
http://msdn.microsoft.com/en-us/library/bb264562.aspx
http://www.devx.com/dbzone/Article/31648
http://msdn.microsoft.com/de-de/library/ms144259.aspx
lg 🙂
Danke für die Tipps !! =)
danke bernd 🙂
werd ich sofort probieren ! =)
[edit] kann ich die installationsroutine auch über c# vllt installieren ?
weil wenn ich jetzt jemandem die software gebe müsste ich in einem manual schritt für schritt erklären was man installieren muss und im prinzip ist es immer gleich.. oder gibts dafür ene alternative ?
(vorallem Passwort eingabe bei gemischte Authentifizierung is doof .. da muss ich das PW im klartext im manual dann angeben oder beim programm anfangs das PW abfragen -> wäre auch eine lösung zumindest)
aber der install prozess wird halt lange
@jack .. aso .. mhm
naja ich konkretisiere mal
Ich hab eine Karteikartenanwendung für User, wo termine eingetragen werden und bilder abgelegt.
Es gibt 2 Computer... Beide sollen die gleichen Daten einsehen können
Da kann ich leider keinen extra Server für DB aufsetzen weil es glaub ich net mal einen admin gibt ^^ .. das ist ein Privat PC...
Wäre das nur 1 Computer würd ich das überhaupt mit einem kleinen internen XML File oder so lösen .. aber dadurch dass ein zweiter zugreifen muss wird das ganze interessant .. vorallem zeitgleicher zugriff (also kein File-Sharing von XML dateien !)
der Client ist nicht das Problem in dem Fall
Das Problemm ist viel mehr, dass die Datenbank sich selber installieren soll 😠
@jack ... Gibts da Schnittstellen mit der man die datenbank von selber installieren kann ?
Bzw. wie löst man allgemein Projekte, die dem Kunden verkauft werden sollen als Paket und auch größere Datenmengen enthalten können ?
Hallo,
Ich soll ein kleines Programm basteln, was u.a. Daten über User, Eigenschaften sowie Bilder speichern soll
Jedoch soll dieses programm auf 2 Workstations laufen.
Keine allzu aufwendige Datenbank, jedoch meine Frage:
Hoffe es ist die richtige Kategorie 🙂
lg
Mhm ..
Wie meinst du das mit dictionary ?
Sozusagen im Vorfeld alle möglichen Indizes aus dem Bild auslesen und in einem Dict speichern ?
Ist das nicht auch bissl ein performance verlust vorher ein bild komplett auszulesen stück für stück ?
ach ich bin ein depp ..
ich nehm einfach das bild andsich als Wert"karte" und dann über koord die farbe wie du sagst .. ..
Danke .. (manchmal denk ich einfach zu verkrampft kompliziert -> dachte an eine große funktion um den wert auszurechnen)
lg
mhm ..
Also das Farbverlauf zeichnen ist ja nicht das problem
Aber ich will jetzt diesen Farbverlauf hernehmen und sozusagen "indizieren" ..
Nehmen wir an ich hab z.b. Höhe 4.21 .. d.h. die Farbe ist daher fast gelb, aber bischen richtung rot
dann bekomm ich eine höhe -6.23 .. d.h die Farbe ist grad noch ein bischen hell, aber doch schon fast dunkelblau
Sozusagen diesen Farbverlauf "indizieren"
Hallo,
Weiß jemand, wie ich aufgrund von Höhenpunkte eine echte "ColorMap" erzeuge. Leider versteht C# unter colormap sowas wie eine umrechnung von existierenden werte in neue, aber ich würde gerne eine neue erzeugen
Das problem ist, dass 5 verschiedene Farbverläufe (siehe Grafik) berücksichtigt werden müssten.
D.h. jeder "pixel" der karte entspricht einer gemessenen Höhe, und diese Höhe "indiziert" eine spezielle Farbe, die aber aufgrund des Farbverlaufs nicht vorher definierbar ist (ausser man rechnet sich alle farben und deren höhenindexe vorher aus -> uff)
Hoffe das Problem hab ich einigermaßen verständlich erklärt.
Hab schon im forum nach ähnlichen themen gesucht, aber ausser auf meine alte heightmap, die jedoch nicht das aktuelle Problem behandelt, bin ich auf nix gestoßen
danke für jede Hilfe
lg
Philipp
Aja, wieder was gelernt ^^ ..
Also ist
using(DBCommand = new OleDBCommand())
{
DBCommand.Connection = this.quelle.DBConn;
....
}
Doch besser ?? ..
Weil dann lass ich this.quelle.DBConn immer offen und schließe es am Ende des programms ?
Oh, einige Ideen, vielen Dank.
Am einfachsten für mich ist das Beispiel von psy, weil ich nie 2 gleiche Pens brauche 🙂 .. Perfekt !
Danke !
mhm ..
Ok ich bin mal so frei .. äh .. hier ist meine singleton Klasse
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
namespace Test
{
/// <summary>
/// Globale Singleton Klasse zur Speicherung von Brushes und Pens
/// </summary>
public sealed class GraphicHelper : IDisposable
{
#region Singleton Pattern
// Zugriff über Singleton s=Singleton.getInstance();
// Hilfsfeld für eine sichere Threadsynchronisierung
private static Object m_lock = new Object();
private GraphicHelper()
{
this.m_brushes = new Dictionary<int, Brush>();
this.m_pens = new Dictionary<string, Pen>();
}
private static volatile GraphicHelper instance = null;
/// <summary>
/// Die Instanz von GraphicHelper
/// </summary>
public static GraphicHelper Instance
{
get
{
// DoubleLock
if (instance == null)
lock (m_lock) { if (instance == null) instance = new GraphicHelper(); }
return instance;
}
}
#endregion
private Dictionary<int, Brush> m_brushes;
private Dictionary<string, Pen> m_pens;
/// <summary>
/// Übergibt ein Brush-Objekt
/// </summary>
/// <param name="color">Farbe des Brushes</param>
/// <returns>der Brush</returns>
public Brush GetBrush(Color color)
{
if (!this.m_brushes.ContainsKey(color.ToArgb()))
this.m_brushes.Add(color.ToArgb(), new SolidBrush(color));
return this.m_brushes[color.ToArgb()];
}
/// <summary>
/// Übergibt ein Pen-Objekt
/// </summary>
/// <param name="color">Farbe des Pens</param>
/// <returns>der Pen</returns>
public Pen GetPen(Color color)
{
if (!this.m_pens.ContainsKey(color.ToArgb().ToString() + "+1"))
this.m_pens.Add(color.ToArgb().ToString() + "+1", new Pen(color));
return this.m_pens[color.ToArgb().ToString() + "+1"];
}
/// <summary>
/// Übergibt ein Pen-Objekt
/// </summary>
/// <param name="color">Farbe des Pens</param>
/// <param name="size">Größe des Pens</param>
/// <returns>der Pen</returns>
public Pen GetPen(Color color, int size)
{
if (!this.m_pens.ContainsKey(color.ToArgb().ToString() + "+" + size.ToString()))
this.m_pens.Add(color.ToArgb().ToString() + "+" + size.ToString(), new Pen(color, size));
return this.m_pens[color.ToArgb().ToString() + "+" + size.ToString()];
}
internal Pen GetPen(Color color, float size)
{
if (!this.m_pens.ContainsKey(color.ToArgb().ToString() + "+" + size.ToString()))
this.m_pens.Add(color.ToArgb().ToString() + "+" + size.ToString(), new Pen(color, size));
return this.m_pens[color.ToArgb().ToString() + "+" + size.ToString()];
}
#region Dispose
private bool disposed = false;
/// <summary>
/// Destruktor, ruft Dispose auf
/// </summary>
~GraphicHelper()
{
Dispose();
}
/// <summary>
/// Releases all Ressources used by this Total_Visualization_Program.GraphicHelper
/// </summary>
public void Dispose()
{
if (disposed) return;
disposed = true;
foreach (KeyValuePair<int, Brush> brush in this.m_brushes)
brush.Value.Dispose();
this.m_brushes = null;
foreach (KeyValuePair<string, Pen> pen in this.m_pens)
pen.Value.Dispose();
this.m_pens = null;
}
#endregion
}
}
Hi,
kann es sein, dass die Lösung zwar "sauberer" ist mit der Singleton Klasse, aber Ressourcenfressender ? ^^ ... Oder zumindest kaum unterschied gibt ? ..
Habs bei 1-2 aufrufen pro Funktion mittels
SingletonGraphic.Instance.GetBrush();
und bei >2 aufrufen pro Funktion mittels:
SingletonGraphic sgraph = SingletonGraphic.Instance;
sgraph.GetBrush();
gelöst
[EDIT]Abgeteilt von Beispielanwendung für Access-Zugriff mit C#[EDIT]
Diesbezüglich hab ich mal gehört, dass DataSets in Performance Sachen vermieden werden sollen..
Inwieweit hast du da Erfahrungen gemacht ? (Das "Gerücht" muss ja nicht zwangsweise wahr sein 🙂 )
[EDIT] Sorry ich dachte dass durch den direkten Zusammenhang es direkt im Thread gepostet werden sollte - danke an den Admin fürs verschieben[/EDIT]
Mhm ..
Also ich hab pro "aufruf" ca. 10 verschiedene Funktionen, die oledbconnection brauchen ..
daher 10x ca. using (oledbconnection conn = new ....)
demnach ist das nicht so wichtig ?
sry 4 doppelpost aber denke sonst haben das schon alle abgeschlossen angesehen ^^
Also ich kann NICHT
using (OleDBConnection conn = this.quelle.DBConn)
{
conn.Open();
}
Weil dann wirft er mir eine exception mit -> ConnectionString nicht initialisiert
using (OleDBConnection conn = this.quelle.DBConn)
{
conn.ConnectionString = this.quelle.DBConn.ConnectionString;
conn.Open();
}
dito Fehlermeldung
Einzig und allein:
using (OleDBConnection conn = new OleDBConnection(this.quelle.DBConn.ConnectionString))
{
conn.Open();
}
funktioniert ...
Aber das is ein Ressourcenfresser (dauernd neues Connection Objekt) oder ? Zumindest bild ich mir ein, dass meine Anwendung jetzt länger braucht 🙁
ha ...
DAS is eine gute lösung
danke dir ..
ja ..
aber die frage ist halt nun
ich verwende DIESE klasse mit diesem objekt andauernd ..
soll ich da jedes mal so machen:
this.quelle.DBConn.Open();
using (DBComm = new OleDBCommand())
{
DBComm.Connection = this.quelle.DBConn;
}
this.quelle.DBConn.Close();
oder einfach
DBComm = new OleDBConnection();
DBComm.Connection = this.quelle.DBConn;
ersteres hätte das problem wenn ich ein if innerhalb des usings hab, was ein "return" auslöst -> wird dann das using abgearbeitet .. und was passiert mit der offenen connection ? die muss ich ja händisch zumachen oder ?
naja ..
es is keine hexerei ..
es is einfach ein Public Propertie OleDBconnection
sprich
class Oledbclass
{
private OleDBConnection m_DBConn;
public OleDBConnection DBConn
{
get { return this.m_DBConn; }
}
}
c'est câ
Mhm ..
Es ist so, dass die seperate Klasse (mit dem OleDBConnection objekt) eine nicht antastbare Klasse ist, weil sie von einem Kollegen aus der Arbeit in VB6 geschrieben wurde und die ganzen Algotrithmen sollte ich in C# übernehmen damit beide Versionen (C# und VB6) gleich sind ..
Sprich auf gut deutsch, das oledbconnection objekt ist leider da ..
Die frage ist nun .. soll ich es einfach schließen und dann wie du beschrieben hast mit der Klasse arbeiten oder ist es gscheiter das OleDBConnection objekt mitzuschleifen ?
verwendetes Datenbanksystem: Jet Engine (MS Access)
Hallo
angenommen ich hab eine OleDBConnection in einer Klasse, nennen wir sie
quelle ..
quelle.DBConn <-- OleDBConnection ..
wenn ich diese DBConn in einigen verschiendenen Funktionen verwende und verschiedenen Klassen, in dem ich sie übergebe ..
in diesen funktionen hab ich dann jeweils ein dbcomm und dbreader mit dem ich arbeite ..
BISHER hab ich einfach die connection IMMER offen gelassen bis zum programmende und dann halt immer wieder neue dbcommands instanziert mit dbreader ..
Fragen dazu:
Fragen über fragen seufz
Vielen Dank für alle Antworten schon mal 🙂