Bildbearbetungsprogramm - Verbesserungen, kleine Fehler



  • Hallo,
    ich habe ein kleines Bildbearbeitungsprogramm in C# geschrieben. Die erste Version wurde viel heruntergeladen und ich bin es am erweitern und verbessern.
    Folgende Probleme bestehen noch:
    - Beim Drucken kann das Bild mittels eines TrackBars an die Seitengrösse angepasst werden. Bei grösserer/häufiger Veränderung wird das Bild verzerrt, es bewegt sich dann mehr in Richtung Quadrat. Was kann ich dagegen tun? Ist das ein Rundungsfehler o.ä., im Ausdruck

    b.Bildverkleinern(s.Height - ((s.Height / 100) * trackBar1.Value), s.Width - ((s.Width / 100) * trackBar1.Value));
    

    ?

    - Bei manchen Bildern (im JPG-Format), wahrscheinlich bei bestimmten Komprimierungsraten/Auflösungen wird das Bild zuerst sehr schlecht dargestellt. Meistens sieht es normal aus sobald einmal der vergrössern- oder verkleinern-Button geklickt wird. Bei manchen Bildern ändert sich aber nichts und sie bleiben schlecht.

    - dann wäre nur noch eine eventuelle Optimierung des Arbeitsspeicherverbrauchs; ich experimentierte wie im Code ersichtlich mit dispose() etc.

    Hier der Quellcode:

    Die Klasse Bildbearbeitung, welche die Bearbeitungsfunktionalität enthält und im Seitenvorschaufenster nochmals zum Einsatz kommt:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    
    namespace Bildbearbeitungsprogramm
    {
        ///<summary>
        ///In dieser Klasse wird die gesamte Funktionalität des Programmes bereitgestellt
        ///   </summary>
        public class Bildbearbeitung
        {
            Bitmap bild; //enthält das Bild; dieses wird bearbeitet, keine Kopie des Originales behalten.
            public Bildbearbeitung(string Filename)
            {
                string Dateiname = Filename;
                bild = new Bitmap(Dateiname, true);
    
            }
            public Bildbearbeitung(Bitmap BildBitmap)
            {
                bild = BildBitmap;
            }
            public Bildbearbeitung() { }
            ///<summary>
            ///Datei hinzufügen (öffnen)
            ///</summary>
            public void addFile(string Filename)
            {
                string Dateiname = Filename;
                bild = new Bitmap(Dateiname, true);
            }
            /// <summary>
            /// Das Bild wird als Bitmap zurückgeliefert (wenn bearbeitet dann die bearbeitete Version)
            /// </summary>
            /// <returns>Bitmap-Objekt (ggf. gedreht, ggf. bearbeitet)</returns>
            public Bitmap GetBitmap()
            {
                return bild;
            }
            /// <summary>
            /// Liefert das Bitmap verkleinert/vergrössert zurück; falls es gedreht wurde dann in der Bearbeiteten Version; int-Wert=Faktor. Die Originalversion bleibt bestehen! Für Zoom-Ansicht
            /// </summary>
            /// <param name="percent"></param>
            /// <returns>verkleinertes/vergrössertes Bitmap-Obj</returns>
            public Bitmap GetBitmapZoom(int percent)
            {
    
                Bitmap bild2 = (Bitmap)bild.GetThumbnailImage((bild.Width * 100) / percent, (bild.Height * 100) / percent, null, IntPtr.Zero);
                return bild2;
            }
            /// <summary>
            /// Verkleinert/vergrössert das Bild nach Höhe/Breite DEFINITIV (keine Kopie wird behalten)
            /// </summary>
            /// <param name="height"></param>
            /// <param name="width"></param>
            /// <returns>Bearbeitetes Bitmap-Obj</returns>
            public Bitmap Bildverkleinern(int height, int width)
            {
    
                Bitmap zielbild;
                zielbild = (Bitmap)bild.GetThumbnailImage(width, height, null, IntPtr.Zero);
                bild = zielbild;
                return zielbild;
    
            }
            /// <summary>
            /// Dreht das Bild (Original) um 90 Grad und liefert es zurück
            /// </summary>
            /// <returns>Gedrehtes Bitmap-Obj</returns>
            public Bitmap Bilddrehen()
            {
    
                bild.RotateFlip(RotateFlipType.Rotate90FlipNone);
                return bild;
            }
    
            /// <summary>
            /// Liefert Bildgrösse zurück
            /// </summary>
            /// <returns>Size-Objekt</returns>
            public Size Bildgroesse()
            {   
                return bild.Size;
            }
        }
    }
    

    Das Hauptprogramm:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    
    namespace Bildbearbeitungsprogramm
    { 
    
        public partial class Form1 : Form
        {
    
            public Form1()
            {
                InitializeComponent();
            }
            public Point pt; //Eingestellte Grösse f. Drucken
            public bool bAenderungen = false;  //Für Rückfrage wg. speichern, global
            public Bildbearbeitung b = new Bildbearbeitung(); //Instanzierung eines globalen Objekts mit den Funktionen des Programmes
    
            private void Form1_Load(object sender, EventArgs e)
            {
                string[]cmdlargs = Environment.GetCommandLineArgs();
                try
                {
                    this.Text = cmdlargs[1] + " - netBildbearbeitungsprogramm";
                    bAenderungen = false;
    
                    b.addFile(cmdlargs[1]);
    
                    pictureBox1.Image = b.GetBitmapZoom(trackBar1.Value);
    
                    Size s = b.Bildgroesse();
                    numericUpDown1.Value = s.Height; numericUpDown2.Value = s.Width;
    
                }
                catch (Exception) { }
    
            }
    
            private void öffnenToolStripMenuItem_Click(object sender, EventArgs e)
            {
                MessageBox.Show("Dies ist eine Shareware-Version. Erwerben sie die Vollversion für Fr. 3.50 / EUR 2.- unter http://rebenstudio-it.ch/~kontaktformular oder http://homepage.hispeed.ch/reben", "Shareware-Hinweis", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
    
                oeffnen();
            }
    
            private void pictureBox1_Click(object sender, EventArgs e)
            {
    
            }
    
            private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
            {
    
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
    
            }
    
            private void numericUpDown1_ValueChanged(object sender, EventArgs e)
            {
    
            }
    
            private void toolStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
            {
    
            }
    
            private void numericUpDown1_KeyUp(object sender, KeyEventArgs e)
            {
    
            }
    
            private void trackBar1_Scroll(object sender, EventArgs e)
            {
    
            }
    
            private void trackBar1_MouseUp(object sender, MouseEventArgs e)
            {
                try
                {
                    pictureBox1.Image = b.GetBitmapZoom(trackBar1.Value);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(("Ein Fehler ist aufgetreten: " + ex.Message.ToString()), "Fehler!", MessageBoxButtons.OK, MessageBoxIcon.Error);
    
                }
    
            }
    
            private void trackBar1_KeyUp(object sender, KeyEventArgs e)
            {
                try
                {
                    pictureBox1.Image = b.GetBitmapZoom(trackBar1.Value);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(("Ein Fehler ist aufgetreten: " + ex.Message.ToString()), "Fehler!", MessageBoxButtons.OK, MessageBoxIcon.Error);
    
                }
    
            }
            private void executeresize()
            {
                try
                {
                    bAenderungen = true;
                    Bitmap bit = b.Bildverkleinern((int)numericUpDown1.Value, (int)numericUpDown2.Value);
                    pictureBox1.Image = bit;
                    GC.Collect();
    
                }
                catch (Exception ex)
                {
                    MessageBox.Show(("Ein Fehler ist aufgetreten: " + ex.Message.ToString()), "Fehler!", MessageBoxButtons.OK, MessageBoxIcon.Error);
    
                }
            }
    
            private void speichernUnterToolStripMenuItem_Click(object sender, EventArgs e)
            {   
                speichernunter();
            }
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            { 
                if (bAenderungen == true)
                {
                    DialogResult d = MessageBox.Show("Das Bild wurde verändert. Sollen die Änderungen gespeichert werden?", "Datei wurde noch nicht gespeichert", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (d == DialogResult.Yes)
                    {
                        if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                        {
                            try
                            {
                                Bitmap tmp = b.GetBitmap();
                                tmp.Save(saveFileDialog1.FileName);
                                //tmp.Dispose();
                                GC.Collect();
                            }
                            catch (Exception ex)
                            {
    
                                MessageBox.Show(("Ein Fehler ist aufgetreten: " + ex.Message.ToString()), "Fehler!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
    
                        }
    
                    }
    
                }
    
            }
                    private void oeffnen() {
                        pruefevoroeffnen();
                        bAenderungen = false;
                        errorProvider1.Clear();
    
                        if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    try
                    { 
                        b.addFile(openFileDialog1.FileName);
    
                        pictureBox1.Image = b.GetBitmapZoom(trackBar1.Value);
    
                        Size s = b.Bildgroesse();
                        numericUpDown1.Value = s.Height; numericUpDown2.Value = s.Width;
                        this.Text = openFileDialog1.FileName + " - netBildbearbeitungsprogramm";
                        GC.Collect();
                    }
                    catch (Exception ex)
                    {
    
                        MessageBox.Show(("Ein Fehler ist aufgetreten: " + ex.Message.ToString()), "Fehler!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                    }
    
            private void speichernunter()
            {
                MessageBox.Show("Dies ist eine Shareware-Version. Erwerben sie die Vollversion für Fr. 3.50 / EUR 2.- unter http://rebenstudio-it.ch/~kontaktformular oder http://homepage.hispeed.ch/reben", "Shareware-Hinweis", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                errorProvider1.Clear();
                try
                {
    
                    if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                    {
                        Bitmap tmp = b.GetBitmap();
                        //tmp.Save("h",System.Drawing.Imaging.ImageFormat.
                        if (saveFileDialog1.FilterIndex == 1)
                        {
                            tmp.Save(saveFileDialog1.FileName);
                        }
                        if (saveFileDialog1.FilterIndex == 2)
                        {
    
                            tmp.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Bmp);
                        }
                        if (saveFileDialog1.FilterIndex == 3)
                        {
    
                            tmp.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Gif);
                            MessageBox.Show("Bei Speichern im GIF-Format treten Qualitäts/Farbverluste auf", "Qualitätsverlust", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }
                        if (saveFileDialog1.FilterIndex == 4)
                        {
    
                            tmp.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Emf);
                        }
                        if (saveFileDialog1.FilterIndex == 5)
                        {
    
                            tmp.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Wmf);
                        }
                        if (saveFileDialog1.FilterIndex==6) {
                            tmp.Save(saveFileDialog1.FileName, System.Drawing.Imaging.ImageFormat.Tiff);
                        }
                        bAenderungen = false;
                        //tmp.Dispose();
                        GC.Collect();
    
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(("Ein Fehler ist aufgetreten: " + ex.Message.ToString()), "Fehler!", MessageBoxButtons.OK, MessageBoxIcon.Error);
    
                }
    
            }
    
            private bool pruefevoroeffnen()
            {
                if (bAenderungen == true)
                {
                    DialogResult d = MessageBox.Show("Das Bild wurde verändert. Sollen die Änderungen gespeichert werden?", "Datei wurde noch nicht gespeichert", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (d == DialogResult.Yes)
                    {
                        if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                        {
                            try
                            {
                                Bitmap tmp = b.GetBitmap();
                                tmp.Save(saveFileDialog1.FileName);
                                //tmp.Dispose();
                                GC.Collect();
                            }
                            catch (Exception ex)
                            {
    
                                MessageBox.Show(("Ein Fehler ist aufgetreten: " + ex.Message.ToString()), "Fehler!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                return false;
                            }
    
                        }
    
                    }
                }
                return true;
            }
            private void button3_Click(object sender, EventArgs e)
            {
                numericUpDown2.Value=numericUpDown2.Value*2;
                numericUpDown1.Value = numericUpDown1.Value * 2;
                executeresize();
                errorProvider1.SetError(button3, "Achtung, Bild wurde vergrössert=Qualitätsverlust (Interpolieren). Für vergrösserte Ansicht Zoom benützen");
    
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                numericUpDown1.Value = numericUpDown1.Value / 2;
                numericUpDown2.Value = numericUpDown2.Value / 2;
                executeresize();
            }
    
            private void beendenToolStripMenuItem_Click(object sender, EventArgs e)
            {
                Form1.ActiveForm.Close();
            }
    
            private void toolStripButton1_Click(object sender, EventArgs e)
            {
                MessageBox.Show("Dies ist eine Shareware-Version. Erwerben sie die Vollversion für Fr. 3.50 / EUR 2.- unter http://rebenstudio-it.ch/~kontaktformular oder http://homepage.hispeed.ch/reben", "Shareware-Hinweis", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
    
                oeffnen();
            }
    
            private void toolStripButton2_Click(object sender, EventArgs e)
            {
                speichernunter();
            }
    
            private void button4_Click(object sender, EventArgs e)
            {
                MessageBox.Show("Dies ist eine Shareware-Version. Erwerben sie die Vollversion für Fr. 3.50 / EUR 2.- unter http://rebenstudio-it.ch/~kontaktformular oder http://homepage.hispeed.ch/reben", "Shareware-Hinweis", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
    
                try
                {
                    bAenderungen = true;
                     b.Bilddrehen();
                     Bitmap bit = b.GetBitmapZoom(trackBar1.Value);
                    pictureBox1.Image = bit;
                    Size s = b.Bildgroesse();
                    numericUpDown1.Value = s.Height; numericUpDown2.Value = s.Width;
                    GC.Collect();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(("Ein Fehler ist aufgetreten: " + ex.Message.ToString()), "Fehler!", MessageBoxButtons.OK, MessageBoxIcon.Error);
    
                }
            }
    
            private void toolStripButton3_Click(object sender, EventArgs e)
            {
                AboutBox1 a = new AboutBox1();
                a.Show();
            }
    
            private void button4_MouseMove(object sender, MouseEventArgs e)
            {
                toolTip1.Show("Bild drehen", this, 500);
            }
    
            private void button4_MouseEnter(object sender, EventArgs e)
            {
                toolTip1.Show("Bild drehen", this, 500);
            }
    
            private void numericUpDown2_ValueChanged(object sender, EventArgs e)
            {
    
            }
    
            private void button1_Click_1(object sender, EventArgs e)
            {
                executeresize();
            }
            void drucken()
            {
                try
                {
    
                    notifyIcon1.Visible = true;
                    notifyIcon1.ShowBalloonTip(1000);
    
                    if (printDialog1.ShowDialog() == DialogResult.OK)
                    {
    
                        printDocument1.PrinterSettings = printDialog1.PrinterSettings;
                        printDocument1.PrinterSettings.PrinterName = printDialog1.PrinterSettings.PrinterName;
                        printDocument1.DocumentName = openFileDialog1.FileName;
    
                        Seiteneinrichtung s = new Seiteneinrichtung(b.GetBitmap(), printDocument1, printDocument1.PrinterSettings);
    
                        s.ShowDialog();
    
                        pt = (Point)s.Tag; //Bildgrösse auf dem Papier, mit dem Dialog vom Benutzer eingestellt
                        printPreviewDialog1.Document = printDocument1;
    
                        if (printPreviewDialog1.ShowDialog() == DialogResult.OK)
                        {
    
                            printDocument1.Print();
                            notifyIcon1.Visible = false;
    
                        }
    
                        else
                            notifyIcon1.Visible = false;
                    }
    
                    else
                        notifyIcon1.Visible = false;
    
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message.ToString(), "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
    
                }
                }
    
            private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
            { 
    
                    Graphics gr = e.Graphics;
                    Image oImage = (b.GetBitmap() as Image);
    
                    Point p = new Point(e.MarginBounds.Left, e.MarginBounds.Top);
                    if (oImage != null)
                    {
                        Rectangle r = new Rectangle(p.X, p.Y, pt.X, pt.Y);
    
                        gr.DrawImage(oImage, r);
                    }
                    gr.Dispose();
    
            }
    
            private void druckenToolStripMenuItem_Click(object sender, EventArgs e)
            {
                drucken();
            }
    
        }
    }
    

    Das Seitenvorschaufenster:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    
    namespace Bildbearbeitungsprogramm
    {///<summary>
     ///Dies ist das Seitenvorschaufenster; die Bildgrösse für den Druck wird hier angepasst.
     ///Dazu benützt die Klasse ein Objekt der Klasse Bildbearbeitung, um die Bildgrösse zu verändern (temporär) und anschliessend wird die Grösse ermittelt und in Tag übergeben.
     /// Die Instanzierung erfordert ein Bitmap "zu druckendes Bild", das Printdocument (mit dem Bild) sowie die Printersettings zur Initialisierung.
        ///</summary>
        ///<remarks>noch in Bearbeitung</remarks>
        public partial class Seiteneinrichtung : Form
        {
            System.Drawing.Printing.PrinterSettings PrintSet = new System.Drawing.Printing.PrinterSettings();
            Bildbearbeitung b;
            Point pTemp = new Point();
            int oldvalue;
    
            public Seiteneinrichtung(Bitmap zuDruckendesBild, System.Drawing.Printing.PrintDocument zudruckendesPrintDocument, System.Drawing.Printing.PrinterSettings Druckereinstellungen)
            {
                printDocument1 = zudruckendesPrintDocument;
                PrintSet = Druckereinstellungen;
                b = new Bildbearbeitung(zuDruckendesBild);
    
                InitializeComponent();
            }
            /// <summary>
            /// Initialisierung mit Daten und Rückgabe der aktuellen Daten falls nichts verändert wird vom Benutzer
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
    
            private void Seiteneinrichtung_Load(object sender, EventArgs e)
            {
                printDocument1.PrinterSettings = PrintSet;
                printPreviewControl1.Document = printDocument1;
                Size sTemp = b.Bildgroesse();
                pTemp.X = sTemp.Width; pTemp.Y = sTemp.Height;
                this.Tag = pTemp;
    
            }
    
            private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
            {
                Graphics gr = e.Graphics;
                Image oImage = (b.GetBitmap() as Image);
    
                Point p = new Point(e.MarginBounds.Left, e.MarginBounds.Top);
                if (oImage != null)
                {
                    Rectangle r = new Rectangle(p.X, p.Y, pTemp.X, pTemp.Y);
    
                    gr.DrawImage(oImage, r);
    
                }
                gr.Dispose();
            }
    
            private void trackBar1_Scroll(object sender, EventArgs e)
            {
    
                Size s=new Size();
                s=b.Bildgroesse();
                if (trackBar1.Value < 0)
                {
                    if (oldvalue < trackBar1.Value)
                    {
                        trackBar1.Value = 0;
                    }
                }
                if (trackBar1.Value>0)
                {
                    if (oldvalue > trackBar1.Value)
                    {
                        trackBar1.Value = 0;
                    }
                }
                try
                {
                    b.Bildverkleinern(s.Height - ((s.Height / 100) * trackBar1.Value), s.Width - ((s.Width / 100) * trackBar1.Value));
                    //Bild wird prozentual verkleinert/vergrössert.
                    printDocument1.PrinterSettings = PrintSet; //Vorschau erstellen
                    printPreviewControl1.Document = printDocument1;
                }
                catch (Exception ex)
                {
    
                    MessageBox.Show(ex.Message.ToString(), "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                Size sTemp = b.Bildgroesse(); //Grösse ermitteln und zurückgeben für Hauptprogramm
    
                pTemp.X = sTemp.Width; pTemp.Y = sTemp.Height;
                this.Tag = pTemp;
                printPreviewControl1.InvalidatePreview();
    
            }
    
            private void trackBar1_MouseUp(object sender, MouseEventArgs e)
            {
                oldvalue = trackBar1.Value;
            }
        }
    }
    

    Vielen vielen Dank für die Anregungen!



  • Überleg mal, was bei "(s.Height / 100)" als Wert herauskommt...

    P.S. Erstell erst einmal ein professionelles Programm, bevor du an das Geldverdienen denkst...

    Du hast soviele Programmier- bzw. Designfehler in deinem Code, da graut es einem ja...
    - möglichst nie GC.Collect() selber aufrufen
    - Benennung der Variablen und Elemente (Form1, button1, ...)
    - falsche Verwendung des Exception-Handlings (höchstens für Testzwecke, aber dafür ist ja der IDE-Debugger dar)
    - niemals für fremde Objekte Dispose aufrufen (z.B. gr.Dispose())
    - ...



  • Natürlich, sollte eine Double-Zahl sein; gibt ein Rundungsfehler, mit der Multiplikation wird dieser dann auch vergrössert.
    Die erste Version des Programmes, konnte nur skalieren, wurde innerhalb weniger Wochen 1500 Mal heruntergeladen und die Sterne für die Nutzerzufriedenheit zeigten immer einen schwankenden Wert von 70-80% an (anscheinend haben einige der Leute bewertet sonst hätte der Wert nicht geschwankt); ist ja nicht schlecht! Die sehen natürlich den Code nicht, aber vielleicht waren diese zufrieden wegen der Einfachheit.

    Zum Exception-Handling; was ist daran schlecht? Die für Benutzer unverständliche Message? "Zu wenig Arbeitsspeicher" ist ja OK; klar wenn kein Bild geöffnet wurde steht etwas von Objektinstanz, aber wenn man nicht selbst darauf kommt dass man ein Bild welches nicht da ist nicht bearbeiten kann...

    GC.Collect(), ich weiss es kann Zeit brauchen dies abzuarbeiten; ich dachte nur um während der Laufzeit möglichst bald wieder neuer Arbeitsspeicher zu beschaffen, da ich gemerkt habe dass das der Schwachpunkt meines Programmes ist; wobei bei 512 Mb RAM geht es i.d.R gut.



  • C. M. Obrecht schrieb:

    GC.Collect(), ich weiss es kann Zeit brauchen dies abzuarbeiten; ich dachte nur um während der Laufzeit möglichst bald wieder neuer Arbeitsspeicher zu beschaffen, da ich gemerkt habe dass das der Schwachpunkt meines Programmes ist; wobei bei 512 Mb RAM geht es i.d.R gut.

    Dann solltest du nach der Ursache des Problems suchen und nicht nur die Symptome bekämpfen. Für mich hört sich das nach einem Memory-Leak an.



  • O.o schrieb:

    Dann solltest du nach der Ursache des Problems suchen und nicht nur die Symptome bekämpfen. Für mich hört sich das nach einem Memory-Leak an.

    So ein Blödsinn!
    Hab ich ja wohl noch nie gehört.
    Memory-Leak.
    Guck da mal, lesen kannst Du ja wohl?

    http://de.wikipedia.org/wiki/Speicherleck



  • C. M. Obrecht schrieb:

    O.o schrieb:

    Dann solltest du nach der Ursache des Problems suchen und nicht nur die Symptome bekämpfen. Für mich hört sich das nach einem Memory-Leak an.

    So ein Blödsinn!
    Hab ich ja wohl noch nie gehört.
    Memory-Leak.
    Guck da mal, lesen kannst Du ja wohl?

    http://de.wikipedia.org/wiki/Speicherleck

    Was möchtest Du mit dem Link sagen?
    Simon



  • Wahrscheinlich will er damit sagen, dass er noch nicht mitbekommen hat, dass es auch in Zeiten von GC Memory-Leaks gibt und dass er es für normal hält, dass ein einfaches Bildbearbeitungsprogramm fast 500 MB Arbeitsspeicher verbraucht ...



  • C. M. Obrecht schrieb:

    Hab ich ja wohl noch nie gehört.

    Willst Du damit jetzt ernsthaft behaupten, daß Aussagen, von denen Du noch nie gehört hast automatisch falsch sein müssen?

    Dein ganzer Code ist voller kleiner und großer Fehler, sowohl Design als auch Logikfehler als auch Programmierfehler...

    Beispiel: Wenn Du Dich fragst warum deine Bildqualität nach "Verkleinern" auf einmal schlecht wird, dann schau Dir mal diese Stelle solange an, bis Du verstehst was Du da falsch machst...

    zielbild = (Bitmap)bild.GetThumbnailImage(width, height, null, IntPtr.Zero);
    bild = zielbild;
    

    und beim Drucken machst Du

    Image oImage = (b.GetBitmap() as Image);
    
                Point p = new Point(e.MarginBounds.Left, e.MarginBounds.Top);
                if (oImage != null)
                {
                    Rectangle r = new Rectangle(p.X, p.Y, pTemp.X, pTemp.Y);
    
                    gr.DrawImage(oImage, r);
    
                }
    

    Klar das die Ausdrucke dann Scheisse aussehen, oder?

    Ausserdem:

    Graphics gr = e.Graphics;
       gr.Dispose();
    

    Dir ist schon klar das das ein schwerer Fehler ist? Du zerstörst hier ein Graphics Objekt das vom Framework verwaltet wird -> bad idea.

    Dein ganzer Code zeigt das Du vom Memory-Management des Frameworks keine Ahnung hast... Noch ein Beispiel? Da:

    Bitmap tmp = b.GetBitmap();
       tmp.Save(saveFileDialog1.FileName);
       //tmp.Dispose();
       GC.Collect();
    

    Das würde Sinn machen wenn GetBitmap eine Kopie anlegt, tut es aber nicht:

    Bitmap bild;
       public Bitmap GetBitmap()
       {
           return bild;
       }
    

    GC.Collect bringt an dieser Stelle absolut gar nichts und Dispose würde das interne Objekt der Klasse zerstören...

    btw: schonmal was von Properties gehört? Oder fällt das auch unter: Hab ich noch nie von gehört, gibt es also nicht.



  • Ist es da eigentlich üblich dass andere unter dem Namen des Threadstarters schreiben!? Der 3. Post ist definitiv nicht von mir.
    Die Bilder sehen nicht schlecht aus nach dem Verkleinern (nur so wie es natürlich normal ist kleiner=schlechter) und die Ausdrucke sehen meist auch OK aus; nur bei wenigen Bildern (mit bestimmten Werten denke ich) nicht, und bei namchen sieht das Bild auf dem Bildschirm solange schlecht aus bis einmal verkleinern/vergrössern angeklickt wird. Wie wenn sich die Anzeige aktualisieren müsste...

    Wegen dem dispose und gc. Collect(), ja klar ich dachte es wäre eine Kopie doch das Objekt muss ja noch vorhanden sein weil in diesem Sinne ein Zeiger zurückgegeben wird (habe ich erst kürzlich im Zusammenhang mit C++ gelesen).



  • Ist es da eigentlich üblich dass andere unter dem Namen des Threadstarters schreiben!? Der 3. Post ist definitiv nicht von mir.

    Du könntest Dich registrieren, dann passiert das nicht mehr.
    Simon



  • C.M.Obrecht schrieb:

    Wegen dem dispose und gc. Collect(), ja klar ich dachte es wäre eine Kopie doch das Objekt muss ja noch vorhanden sein weil in diesem Sinne ein Zeiger zurückgegeben wird (habe ich erst kürzlich im Zusammenhang mit C++ gelesen).

    Falsch. Selbst wenn ein Zeiger zurückgegeben würde, wäre dies keine Kopie des Objektes. Jedoch arbeitet C# mit REFERENZEN (jaja, so ähnlich wie Zeiger, aber eben nur so ähnlich). Du kannst 1000 Referenzen auf ein Objekt haben, es ist immer noch nur genau ein Objekt. Solange noch eine Referenz existiert lebt das Objekt weiter. Sind alle Referenzen weg, wird das Objekt (früher oder später) abgeräumt. Lernt ihr Kinder denn nichts über GCs?

    C.M.Obrecht schrieb:

    Die Bilder sehen nicht schlecht aus nach dem Verkleinern (nur so wie es natürlich normal ist kleiner=schlechter) und die Ausdrucke sehen meist auch OK aus; nur bei wenigen Bildern (mit bestimmten Werten denke ich) nicht, und bei namchen sieht das Bild auf dem Bildschirm solange schlecht aus bis einmal verkleinern/vergrössern angeklickt wird. Wie wenn sich die Anzeige aktualisieren müsste...

    Ok, dann muß ich Dir doch wohl erklären was Dein Programm an der Stelle macht.

    Kurz: Du ersetzt das Originalbild (volle Auflösung, optimale Qualität) durch das Thumbnail (geringe Auflösung, niedrige Qualität).

    Je nach Format haben Bilder ein zusätzliches Thumbnail gespeichert in der Größe 120x120. Wenn Du jetzt GetThumbNail(800,400) benutzt wird das 120x120 Thumbnail des Bildes genommen und hochskaliert, ergo Schrott Bildqualität.

    Wenn kein explizites Thumbnail vorhanden ist (je nach Bildformat) dann wird tatsächlich ein echtes Thumbnail erzeugt in der gewünschten Auflösung indem das Originalbild herunterskaliert wird -> Ergo gute Bildqualität.

    Woher ich das weis? Nennt sich MSDN Dokumentation...

    Was lernen wir daraus: Man sollte eine Funktion nicht zu anderen Zwecken mißbrauchen als sie gedacht ist. GetThumbNail ist numal nur genau dazu zu gebrauchen das man ein Thumbnail mit niedriger Qualitöt erzeugt. Du mißbrauchst die Funktion um damit Bilder von beliebiger Größe zu produzieren. Dafür ist es aber nicht gedacht.



  • theta schrieb:

    Ist es da eigentlich üblich dass andere unter dem Namen des Threadstarters schreiben!? Der 3. Post ist definitiv nicht von mir.

    Du könntest Dich registrieren, dann passiert das nicht mehr.
    Simon

    Ode rmachs wie ich, sei ein Arschloch. Dann will keiner unter Deinem Namen posten 😉



  • Ja registrieren werde ich mich nächstens müsen; passierte mir hier nicht das erste Mal.

    Vielen Dank! Ich kannte die Klassen eben nicht wirklich (hatte 2 Kurse über Grundlagen von C# aber nicht über .NET das kommt erst), und als ich mich erkundigte wie ein Bild zu skalieren sei wurde GetThumbnail gezeigt; ich wunderte mich schon! Alles klar, bei den Bildern die schlecht bleiben, bei denen ist ein Thumbnail vorhanden!

    Gibt es denn eine Methode um das Bild korrekt zu skalieren?



  • So jetzt bin ich mal registriert 🙂


Anmelden zum Antworten