Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Portal
  • |
  • Mitglieder
Beiträge von el_vital
Thema: PrintPage, e.Graphics.DrawImage und Positionierung
Am im Forum: Rund um die Programmierung

Ist es eigentlich immer sicher gestellt, dass alle Drucker die GraphicsUnit.Display verwenden und dass es immer 1/100 Zoll ist?

Und wie rechne ich damit Display in Pixel um? Die Druckbreite des Druckers ist z.B. 500 und wenn ich davon ausgehe, dass es in GraphicsUnit.Display ist und immer 1/100, wie viele Pixel bekomme ich bei 600DPI?

Und das mit 600DPI verstehe ich auch nicht. Bei meinem Drucker steht in der Dokumentation Fotodruck mit bis zu 9.600 x 2.400 dpi. Egal was ich einstelle, hat das Graphic-Objekt von PrintPage bei diesem Drucker immer 600DPI. Oder ist es von Papiergröße abhängig? Irgendwie verstehe die ganzen zusammenhänge nicht.

Thema: PrintPage, e.Graphics.DrawImage und Positionierung
Am im Forum: Rund um die Programmierung

Was mich noch mehr verwirrt ist das Verhalten der Drucker im Bezug auf die Druckqualität. In den Einstellungen des Druckers lassen sich z.B. 3 Druckqualitätstuffen einstellen. Einfach, Standrad und Hoch. Wenn ich aber im Programm die Auflösung auslese, dann ist es immer 600DPI und die Druckbreite x Druckhöhe = 600 x 400 Pixel. Unabhängig davon was eingestellt ist.

Thema: PrintPage, e.Graphics.DrawImage und Positionierung
Am im Forum: Rund um die Programmierung

Hallo herbivore,

ich habe mal gelesen, dass die DrawImage Methode nur GraphicsUnit Pixel unterstützt. Also fallen die Millimeter weg. Ich versuche mal alles komplett auf Pixel umzustellen.

Thema: PrintPage, e.Graphics.DrawImage und Positionierung
Am im Forum: Rund um die Programmierung

Hallo Th69,

danke für deine Antwort. Wenn ich das hier mache:


e.Graphics.DrawImage(Bild, destRect, 0, 0, Bild.Width, Bild.Height, System.Drawing.GraphicsUnit.Pixel);                    

Dann sind doch die beiden Einheiten unterschiedlich. Das von dem e.Graphics ist GraphicsUnit.Display und von dem bild GraphicsUnit.Pixel. Wenn ich die GraphicsUnit des Graphic-Objekts auf Pixel setze, dann passt es noch weniger. Es wird dann alles klein gedruckt.

Thema: PrintPage, e.Graphics.DrawImage und Positionierung
Am im Forum: Rund um die Programmierung

Ich versuche gerade ein bild auf einem 10x15 Papier in einem Fotodrucker Rechtsbündig und unten zu drucken.

Das Bild zeichne ich in einem PrintPage Ereignis eines PrintDocument.


printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
...
}

Ich habe Probleme das Bild rechts anzuordnen. Es gibt ja sachen wie:


e.PageSettings.HardMarginX;
e.PageSettings.HardMarginY; 
e.PageSettings.PrintableArea.Height
e.PageSettings.PrintableArea.Width
e.PageSettings.PrintableArea.Left
e.PageSettings.PrintableArea.Right
e.PageSettings.PrintableArea.Top
e.PageSettings.PrintableArea.Bottom

Und das ganze ist in g.PageUnit = GraphicsUnit.Display.

Mein Bild ist z.B. 9cm x 12cm und muss in genau diesen Maßen gedruckt werden.

Jetzt lassen wir mal e.PageSettings.Landscape bei Seite und betrachten nur den Hochformat. Ich muss zum Zeichnen die X-Position richtig berechnen.

Ich zeichne ganz normal mit:


g.DrawImage(Bild, fX, fY, fFormatBreitePixel, fFormatHoehePixel);

Wobei fFormatBreitePixel & fFormatHoehePixel so bestimmt werden:


dFormatBreite = 9;
dFormatHoehe = 12;
float fFormatBreitePixel = (float)(dFormatBreite / 0.0254);
float fFormatHoehePixel = (float)(dFormatHoehe / 0.0254);

Das Problem ist die X-Position. Egall wie ich es berechne, es wird immer anders gedruckt als in einem PrintPreviewControl.

Eins der Berechnungen, die für mich logisch ist, sieht so aus:


double dFormatBreitePixel = dFormatBreite / 0.0254;
dX = (float)(e.PageSettings.PrintableArea.Right - dFormatBreitePixel );

Ich habe die noch bedruckbare Position rechts, ziehe davon die Breite des Bildes ab und erhalte dadurch die X-Position wo ich anfange zu zeichnen. Das Bild wird aber rechts beschnitten gedruckt.

Was mache ich falsch? Hat jemand Erfahrungen in diesem Bereich?

Thema: Öffnen & Vorverarbeiten eines Bildes in einen extra Thread packen, um das GUI nicht zu blockieren?
Am im Forum: GUI: Windows-Forms

An einen timer habe ich auch bereits gedacht. Allerdings mit einem Interval von 30 Sekunden. Das ist wahrscheinlich auch übertrieben und störend.

Thema: Öffnen & Vorverarbeiten eines Bildes in einen extra Thread packen, um das GUI nicht zu blockieren?
Am im Forum: GUI: Windows-Forms

Hallo gfoidl,

danke für den Hinweis. Ich halte den Aufruf von GC.Collect() für Glaubensfrage. Ich persönlich finde es gut die 100MB Speicher, die ein sehr großes Bild bei dieser Funktion verbraucht, unverzüglich frei zu geben. Ich kann es nicht mit ansehen wenn bei Bearbeitung von einigen großen bitmaps der Speicherverbrauch meines Programms auf 500MB und mehr ansteigt. Nach einem GC.Collect() sind es nur noch 90MB.

Thema: Öffnen & Vorverarbeiten eines Bildes in einen extra Thread packen, um das GUI nicht zu blockieren?
Am im Forum: GUI: Windows-Forms

Hier ist mein Code, falls es mal jemand braucht. Es funktioniert jetzt wie ich es mir gewünscht hatte. Danke nochmal an alle.


public static Bitmap LoadBildVerkleinertWPF(string sPfad, int iMaxPixel)
        {
            FileStream myFileStream = File.Open(sPfad, FileMode.Open, FileAccess.Read);
            BitmapFrame Photo = ReadBitmapFrame(myFileStream);

            double WidthNew, HeightNew;
            double dVerhaeltnis = 1;
            if (Photo.PixelWidth > Photo.PixelHeight)
            {
                WidthNew = iMaxPixel;
                HeightNew = (double)Photo.Height * (double)iMaxPixel / (double)Photo.Width;

                dVerhaeltnis = ((WidthNew * 100f) / Photo.PixelWidth) / 100f; ;
            }
            else
            {
                HeightNew = iMaxPixel;
                WidthNew = (double)Photo.Width * (double)iMaxPixel / (double)Photo.Height;
                double EinPro = Photo.PixelHeight / 100f;
                dVerhaeltnis = (HeightNew / EinPro) / 100f;
            }
			
            ScaleTransform st = new ScaleTransform(dVerhaeltnis, dVerhaeltnis, 0, 0);

            TransformedBitmap transformedBitmap = new TransformedBitmap(Photo, st);

            BitmapFrame Thumb = BitmapFrame.Create(transformedBitmap);

            byte[] baResize = ToByteArray(Thumb);

            ImageConverter ic = new ImageConverter();
            Image img = (Image)ic.ConvertFrom(baResize);
            Bitmap bitmap = new Bitmap(img);
            bitmap.SetResolution(350, 350);

            myFileStream.Close();
            myFileStream.Dispose();
            img.Dispose();
            GC.Collect();
            return bitmap;
        }

Thema: Öffnen & Vorverarbeiten eines Bildes in einen extra Thread packen, um das GUI nicht zu blockieren?
Am im Forum: GUI: Windows-Forms

Zitat von winSharp93
Wie hast du das Speicherleck "entdeckt" bzw. woran erkennst du es?

BTW: Einen MemoryStream aus dem Rückgabewert von File.ReadAllBytes zu erstellen ist eher suboptimal ;)

Bezüglich des Speicherlecks habe ich mich wohl getäuscht. Der Speicherverbrauch steigt nur einmal und wird nicht frei gegeben, wenn ich aber mehrere Operationen durchführe steigt es nicht weiter an.

Was ist die Alternative zu dem hier?


byte[] Source = File.ReadAllBytes(FileName);
            Stream stream = new MemoryStream(Source);
            BitmapFrame Photo = ReadBitmapFrame(stream);

Thema: Öffnen & Vorverarbeiten eines Bildes in einen extra Thread packen, um das GUI nicht zu blockieren?
Am im Forum: GUI: Windows-Forms

winSharp93, das habe ich leider übersehen.

Ich habe es gerade ausprobiert. Grundsätzlich ist es möglich und gar nicht mal schlecht, aber es werden Ressourcen nicht frei gegeben und es entsteht ein Speicherleck. Ich sehe nicht wo.

Bei diesem Code geht bereits Speicher verloren, ohne dass ich daraus ein ByteArray und daraus wieder eine Bitmap erstelle. Muss ich noch etwas frei geben?


  string FileName = "Test.jpg";
            byte[] Source = File.ReadAllBytes(FileName);
            Stream stream = new MemoryStream(Source);
            BitmapFrame Photo = ReadBitmapFrame(stream);
            
            ScaleTransform st = new ScaleTransform(0.5, 0.5, 0, 0);

            TransformedBitmap transformedBitmap = new TransformedBitmap(Photo, st);

            BitmapFrame Thumb = BitmapFrame.Create(transformedBitmap);

            stream.Close();
            stream.Dispose();

Thema: Öffnen & Vorverarbeiten eines Bildes in einen extra Thread packen, um das GUI nicht zu blockieren?
Am im Forum: GUI: Windows-Forms

Was meint ihr zu der Lösung das Bild in einer Windows-Form-Anwendung intern mit WPF zu laden, zu verkleinern und über ein ByteArray zurück in ein Bitmap-Objekt zu konvertieren und wie gewohnt weiter zu verwenden? Spricht etwas dagegen?

Thema: Öffnen & Vorverarbeiten eines Bildes in einen extra Thread packen, um das GUI nicht zu blockieren?
Am im Forum: GUI: Windows-Forms

Vielen Dank herbivore für deine Versuche.
Ich überlege das Zeichnen in kleine Schritte zu unterteilen.
Ich könnte das eine Bild auch selbst unsafe auf das andere kopieren und dabei Pixel auslassen. Es wäre auch verkleinert, allerdings ohne irgend einer Interpolation.

Thema: Öffnen & Vorverarbeiten eines Bildes in einen extra Thread packen, um das GUI nicht zu blockieren?
Am im Forum: GUI: Windows-Forms

herbivore hat mich netterweise gebeten ein Mini-Projekt anzuhängen, welches das Verhalten vorführt. (Trotz: 4.1 Bitte keine kompletten Projekte anhängen)

Hier ist es nun. Ich hoffe immer noch für dieses Problem eine Lösung zu finden.

Thema: Öffnen & Vorverarbeiten eines Bildes in einen extra Thread packen, um das GUI nicht zu blockieren?
Am im Forum: GUI: Windows-Forms

Eine Frage habe ich noch. In meinem GUI Thread lasse ich jetzt eine Animation laufen. Es läuft auch flüssig bis in einem zweiten Thread folgendes passiert:


    Bitmap btmTemp = new Bitmap(BreiteNeuTemp, HoeheNeuTemp);
                    Graphics gf = Graphics.FromImage(btmTemp);
                    
                    gf.CompositingQuality = CompositingQuality.HighQuality;
                    gf.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    gf.SmoothingMode = SmoothingMode.HighQuality;
                    gf.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                    

                    gf.DrawImage(btmUebergabe, new Rectangle(0, 0, BreiteNeuTemp, HoeheNeuTemp), new Rectangle(0, 0, btmUebergabe.Width, btmUebergabe.Height), GraphicsUnit.Pixel);
                  

Während der Operation gf.DrawImage stockt meine Animation in dem Haupt-Thread. Wie kann es passieren? Die CPU Kerne sind nur leicht ausgelastet und es sollte die GUI doch überhaupt nicht beeinflussen?

Thema: Öffnen & Vorverarbeiten eines Bildes in einen extra Thread packen, um das GUI nicht zu blockieren?
Am im Forum: GUI: Windows-Forms

WOW, ich bin begeistert. Ich habe die Funktion in ein extra Thread ausgelagert und nicht nur das ich jetzt bequem eine "Bitte warten" Animation anzeigen kann, die Abarbeitung ist fast doppelt so schnell. In dem GUI Thread haben also Timer und verschiedenen Events die Abarbeitung zwischen durch gestört.

Danke für den Schubs in die richtige Richtung!

Thema: Öffnen & Vorverarbeiten eines Bildes in einen extra Thread packen, um das GUI nicht zu blockieren?
Am im Forum: GUI: Windows-Forms

Ich danke euch für die Meinungen. Ganz tief im Inneren weiß ich, dass es sinnvoll und sauber ist solch eine Aufgabe in einen eigenen Thread auszulagern. Jedoch sperrt sich meine Faulheit und mein geringes Wissen in diesem Bereich das auch zu tun.

Wenn ich mal mehr zeit habe werde ich es so umsetzen. Das Problem ist, dass der Code in dem jetzigen Zustand nicht direkt in ein Thread auszulagern ist. Es ist nicht sauber programmiert und es gibt im Ablauf zu viele Zugriffe auf die GUI.

Thema: Öffnen & Vorverarbeiten eines Bildes in einen extra Thread packen, um das GUI nicht zu blockieren?
Am im Forum: GUI: Windows-Forms

Ich habe in meinem Programm eine Funktion bei der der Benutzer ein Bild von einem Speichermedium auswählt. Nach der Auswahl wird es vorverarbeitet und angezeigt.
Diese Aktion mit Öffnen des Bildes, Vorverarbeitung und anschließendem Refresh() der PictureBox wo das Bild angezeigt wird, dauert rund 2 Sekunden. In dieser Zeit zeige ich ein Wait-Cursor an.

Jetzt habe ich hier im Forum gelesen, dass man Aktionen die länger als 1/10s dauern in eine extra Thread auslagern sollte. Macht es in diesem Fall Sinn? Auch wenn der Benutzer in diesen 2 Sekunden sowieso nichts anderes machen kann?

Thema: Flackern beim Zoomen einer PictureBox
Am im Forum: Grafik und Sound

oh, ich habe gerade eine Lösung gefunden. Wenn ich die pictureBox in eine weitere Picturebox anstatt eines Panels packe, dann gibt es diese Probleme nicht. Schade, dass eine Picturebox nicht in dem Designer Child-Elemente aufnehmen kann.

Nachtrag: das geht auch mit einem Panel. Also Panel ableiten, DoubleBuffer Style zuweisen und dieses Panel als Untergrund verwenden.

Thema: Flackern beim Zoomen einer PictureBox
Am im Forum: Grafik und Sound

Hallo herbivore,

ich habe die PictureBox dafür extra abgeleitet:


   class myPictureBox : PictureBox
    {
        public myPictureBox()
        {
            this.SetStyle(

              ControlStyles.AllPaintingInWmPaint |

              ControlStyles.UserPaint |

              ControlStyles.DoubleBuffer, true);

        }
    }

Oder ist es so falsch?

Thema: Flackern beim Zoomen einer PictureBox
Am im Forum: Grafik und Sound

Ich habe die wichtigsten Themen zu dem Flackern eines Controls durchgelesen und schon alles durchprobiert, aber ich bekomme eine PictureBox nicht ohne Flackern vergrößert bzw. verkleinert.

Die PictureBox ist in einem Panel, beinhaltet ein Bild und SizeMode ist auf Zoom eingestellt. Die Größe wird über eine TrackBar mit diesem Code verändert:


   private void trackBar1_ValueChanged(object sender, EventArgs e)
        {
            pictureBox.SuspendLayout();

            int TempVar = 0;

            TempVar = trackBar1.Value - pictureBox.Height;

            if (TempVar < 0)
            {
                TempVar = TempVar * -1;
                if ((pictureBox.Width - TempVar) ≥ 50)
                {
                    pictureBox.Size = new System.Drawing.Size(pictureBox.Width - TempVar, trackBar1.Value);
                    pictureBox.Location = new System.Drawing.Point((int)Math.Round(pictureBox.Location.X + TempVar / 2f), (int)Math.Round(pictureBox.Location.Y + TempVar / 2f));  //--- Position des Vorschaubildes
                }
                else
                    return;
            }
            else
            {
                pictureBox.Size = new System.Drawing.Size(pictureBox.Width + TempVar, trackBar1.Value);
                pictureBox.Location = new System.Drawing.Point((int)Math.Round(pictureBox.Location.X - TempVar / 2f), (int)Math.Round(pictureBox.Location.Y - TempVar / 2f));  //--- Position des Vorschaubildes
            }

            pictureBox.ResumeLayout();
        }


Könnt ihr mir noch ein paar Tipps geben? Es flackert wenn die Ränder des Bildes zu sehen sind. Also wenn das Bild relativ klein ist.

Danke im Voraus.

Thema: Cursor.Hide() wirkt nicht im "Windows XP Mode" unter Windows 7
Am im Forum: GUI: Windows-Forms

Es gibt vorsichtige Nutzer die die Anwendung erst in der Virtuellen Maschine laufen lassen. Es hatten sich bei mir drei Leute deswegen gemeldet und darauf hin habe ich es überprüft.

Thema: Cursor.Hide() wirkt nicht im "Windows XP Mode" unter Windows 7
Am im Forum: GUI: Windows-Forms

Hallo,

ich habe ein Problem in dem 16 Bit Farbmodus unter Windows XP festgestellt. Dort funktioniert die Funktion Cursor.Hide(); nicht. Das Problem wurde mir letzte Zeit öfters gemeldet weil der "Windows XP Mode" unter Windows 7 auf 16Bit eingestellt ist.

Kennt jemand vielleicht eine Lösung dafür?


EDIT: Ich sehe gerade, dass es nichts mit 16Bit Farbqualität, sondern mit Integrationsfeatures zu tun hat. Da kann man wahrscheinlich nichts dran ändern.

Thema: Zu seltenes MouseMove Ereignis / Umgehungslösung des Problems
Am im Forum: GUI: Windows-Forms

Ich habe es jetzt so gemacht wie ich es vor hatte. Ich zeichne die fehlende Strecke zwischen den MouseMove-Ereignissen nach. Allerdings habe ich das Zeichnen auf 1ms reduziert. Ich hatte jedes mal bitmap.LockBits() durchgeführt und nach dem zeichnen wieder frei gegeben. Jetzt mache ich es nur bei MouseDown und gebe es bei MouseUp wieder frei.

Thema: Zu seltenes MouseMove Ereignis / Umgehungslösung des Problems
Am im Forum: GUI: Windows-Forms

Zitat von winSharp93
Du kannst versuchen, das Zeichen und Verarbeiten komplett asynchron zu implementiern

Jede Aktion (Zeichnen) ist von der vorherigen abhängig, also muss es schon synchron ablaufen.
Zitat von winSharp93
Alternativ könntest du mal einen Blick auf DirectInput werfen - evtl. lassen sich damit höhere Inputfrequenzen erreichen. Allerdings kommt ein wenig Aufwand für Umrechnungen etc. hinzu.

Danke für das Stichwort, ich schaue es mir an.

Thema: Zu seltenes MouseMove Ereignis / Umgehungslösung des Problems
Am im Forum: GUI: Windows-Forms

Ich versuche ein Stempelwerkzeug zum retuschieren von Bildern zu implementieren.
Soweit funktioniert alles. Nur das MouseMove wird nicht oft genug ausgelöst um bei schnelleren Mausbewegung durchgehend zu zeichnen. Meine Funktion zum zeichnen ist parallelisiert und optimiert, so dass es im Schnitt 15ms für die Abarbeitung benötigt.

Jetzt kann ich mir die alte Mausposition merken und eine Differenz mit der neuen Bilden. In diesem Abstand muss ich dann alles zeichnen. Ich habe also zwei Punkte mit den jeweiligen X/Y- Koordinaten. Ich müßte mir die Steigung errechnen und zu jedem X-Wert den Y-Wert errechnen und zeichnen. Beziehungsweise würde ich nicht auf jedem Punkt zeichnen, sondern an jedem Viertel des Radius meines Werkzeugs.

Oder gibt es eine Möglichkeit die aktuelle Mausposition öfters zu bekommen?

Thema: Directory.GetDirectories ("C:\\Users\\VS\\AppData\\Local", "*test*", SearchOption.AllDirectories);
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Super. Vielen Dank herbivore!

Thema: Directory.GetDirectories ("C:\\Users\\VS\\AppData\\Local", "*test*", SearchOption.AllDirectories);
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Wenn ich unter Windows 7 folgendes mache:
Directory.GetDirectories("C:\\Users\\VS\\AppData\\Local", "*test*", SearchOption.AllDirectories);

Bekomme ich eine Exception:

System.UnauthorizedAccessException:

Der Zugriff auf den Pfad "C:\Users\VS\AppData\Local\Anwendungsdaten\" wurde verweigert.

Unter Windows XP funktionierte es noch.

Gibt es eine Alternative zu Directory.GetDirectories() wo alle Verzeichnisse zurück geliefert werden auf die Zugriff möglich ist?

Thema: GetDirectories() unter Fat32 liefert die Einträge unsortiert
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Dieses Tool kann die Einträge sehr schnell umsortieren. Es scheint so zu sein, dass die Indizes in der Datentabelle einfach geändert werden.
Ich finde aber leider keine Informationen darüber wie es gemacht wird.

Thema: GetDirectories() unter Fat32 liefert die Einträge unsortiert
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Das Thema ist zwar schon sehr alt, aber genau darum geht es bei meiner Frage.
Ich möchte ein kleines Programm für mich programmieren um den Inhalt einer Fat32 Speicherkarte nach meinem Wunsch zu sortieren.

Die Dateien werden unter Windows zwar sortiert angezeigt, aber in Geräten mit embedet Systemen sind die Dateien durcheinander. Ich nehme an, dass es die Reihenfolge wie die Daten auf das Dateisystem geschrieben wurden.

Gibt es eine einfache Möglichkeit die Reihenfolge unter C# zu beeinflussen?

Thema: Logging in Textdatei mit begrenzter Länge
Am im Forum: Datentechnologien

verwendetes Datenbanksystem: Dateisystem/Textfile

Ich suche eine einfache Logging-Klasse die eine einfache Textdatei beschreibt und die Länge der Datei durch die maximale Anzahl der Zeilen verwaltet.

Ich hatte soetwas hier mal im Forum gesehen, finde es aber leider nicht wieder. Das gute an der Klasse war auch, dass neue Einträge oben hinzugefügt wurden und wenn die max. Länge auf 1000 Zeilen eingestellt war, dann wurde nach dem Erreichen der Zahl immer die letzte Zeile gelöscht.

Es muss nicht multi-thread-sicher sein. Vielleicht kann mir jemand ein Tip geben wo ich soetwas finden kann. Ich habe jetzt leider keine Zeit es selbst zu programmieren. Und etwas wie Log4Net ist für diesen Zweck zu viel.

Danke im Voraus.