Bild größe ändern und speichern, aber Datei ist noch geöffnet

  • C#

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von Trade.

    Bild größe ändern und speichern, aber Datei ist noch geöffnet

    Hi,
    Ich will in einem Programm zum Bilderanzeigen die Größe der Bilder auf HD beschränken und dann speichern.
    Code zum Bearbeiten und Speichern ist das hier:

    Quellcode

    1. FileHandling.AdaptImage(imgPath).Save(imgPath, System.Drawing.Imaging.ImageFormat.Png); }

    Spoiler anzeigen

    Quellcode

    1. public static Image AdaptImage(Image oldImage)
    2. {
    3. if (oldImage.Height > Properties.Settings.Default.defaultHeight)
    4. {
    5. double FactorHeight = Properties.Settings.Default.defaultHeight / (double)oldImage.Height;
    6. int nWidth = Convert.ToInt32(FactorHeight * (double)oldImage.Width);
    7. oldImage = new System.Drawing.Bitmap(oldImage, nWidth, Convert.ToInt32(Properties.Settings.Default.defaultHeight));
    8. }
    9. if (oldImage.Width > Properties.Settings.Default.defaultWidth)
    10. {
    11. double FactorWidth = Properties.Settings.Default.defaultWidth / (double)oldImage.Width;
    12. int nHeight = Convert.ToInt32(FactorWidth * (double)oldImage.Height);
    13. oldImage = new System.Drawing.Bitmap(oldImage, Convert.ToInt32(Properties.Settings.Default.defaultWidth), nHeight);
    14. }
    15. return oldImage;
    16. }

    Dabei bekomm ich immer nen allgemeinen Fehler in GDI+ beim Speichern. Ich befürchte, weil ich das Bild im Programm quasi iwo geöffnet habe, aber ich weiß net wo.
    Das Programm ist eine WPF Anwendung bei denen Images auf nem Fenster sind, deren Source der imgPath ist. Ansonsten speicher ich nur die Pfade und hab nirgens die Bildadtei wirklich geöffnet. Und der Fehler tritt auch auf, wenn die Images als Source noch null haben... :?:
    Probier mal

    C-Quellcode

    1. Bitmap newImage = new Bitmap(oldImage, ...);
    2. return newImage;
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Da stimmt doch was nicht

    Sederic Enders schrieb:

    Quellcode

    1. FileHandling.AdaptImage(imgPath).Save(imgPath, System.Drawing.Imaging.ImageFormat.Png); }

    Quellcode

    1. public static Image AdaptImage(Image oldImage)
    2. {
    3. if (oldImage.Height > Properties.Settings.Default.defaultHeight)
    4. {
    5. double FactorHeight = Properties.Settings.Default.defaultHeight / (double)oldImage.Height;
    6. int nWidth = Convert.ToInt32(FactorHeight * (double)oldImage.Width);
    7. oldImage = new System.Drawing.Bitmap(oldImage, nWidth, Convert.ToInt32(Properties.Settings.Default.defaultHeight));
    8. }
    9. if (oldImage.Width > Properties.Settings.Default.defaultWidth)
    10. {
    11. double FactorWidth = Properties.Settings.Default.defaultWidth / (double)oldImage.Width;
    12. int nHeight = Convert.ToInt32(FactorWidth * (double)oldImage.Height);
    13. oldImage = new System.Drawing.Bitmap(oldImage, Convert.ToInt32(Properties.Settings.Default.defaultWidth), nHeight);
    14. }
    15. return oldImage;
    16. }
    Der Aufruf den du zeigst scheint einen Pfad zu übergeben, aber die Methode erwartet ein Image.

    ErfinderDesRades schrieb:

    Der Aufruf den du zeigst scheint einen Pfad zu übergeben, aber die Methode erwartet ein Image.

    ähm ne, oder? AdaptImage() gibt ein Image zurück, das dann gespeichert wird. Ich geb zu, Einzeiler sind für Fragen ungeeignet, drum mal ein neuer Code mit Anpassungen von RodFromGermany:

    RodFromGermany schrieb:

    Bitmap newImage = new Bitmap(oldImage, ...);


    Quellcode

    1. if (System.IO.File.Exists(imgPath))
    2. {
    3. Bitmap nImg = FileHandling.AdaptImage(new Bitmap(imgPath));
    4. nImg.Save(imgPath, System.Drawing.Imaging.ImageFormat.Png);
    5. }

    Spoiler anzeigen

    Quellcode

    1. public static Bitmap AdaptImage(Bitmap oldImage)
    2. {
    3. Bitmap newPictureH, newPictureW;
    4. if (oldImage.Height > Properties.Settings.Default.defaultHeight)
    5. {
    6. double FactorHeight = Properties.Settings.Default.defaultHeight / (double)oldImage.Height;
    7. int nWidth = Convert.ToInt32(FactorHeight * (double)oldImage.Width);
    8. newPictureH = new System.Drawing.Bitmap(oldImage, nWidth, Convert.ToInt32(Properties.Settings.Default.defaultHeight));
    9. }
    10. else { newPictureH = oldImage; }
    11. if (newPictureH.Width > Properties.Settings.Default.defaultWidth)
    12. {
    13. double FactorWidth = Properties.Settings.Default.defaultWidth / (double)oldImage.Width;
    14. int nHeight = Convert.ToInt32(FactorWidth * (double)oldImage.Height);
    15. newPictureW = new System.Drawing.Bitmap(oldImage, Convert.ToInt32(Properties.Settings.Default.defaultWidth), nHeight);
    16. }
    17. else { newPictureW = newPictureH; }
    18. oldImage.Dispose(); newPictureH.Dispose();
    19. return oldImage;
    20. }

    Frage an der Stelle: Wie ist das mit den Image.Dispose() muss man das machen um Speicher freizukriegen, oder wird das automatisch gemacht, wenn die lokale Variable "ungültig" wird...

    Jetzt bekomm ich den Fehler: "Ungültiger Parameter".
    Der Fehler tritt übrgs erst beim Speichern auf... Ich denke die Zuschneide-Methode (AdaptImage) ist richtig...
    ok ich steh grad übelst aufm Schlauch: Ich ruf doch AdaptImage mit dem Parameter:

    Quellcode

    1. new Bitmap(imgPath)
    auf (davor wars n Image). Das ist doch ein Bitmap und kein String?!

    P.S.: Der Fehler liegt im Speichern, weil ichs an ner anderen Stelle genauso gemacht habe ohne AdaptImage... und da kommt auch der Fehler. Allerdings blockiert mein Prog glaub ich nicht das Speichern, indems iwo geöffnet ist, da ich das Bild in der Zeit auch löschen kann...
    Jop is n String, wie kann ich nur so blind sein?!?! ABer jetzt ist es ein Bitmap, oder täusch ich mich? :D Das Prob besteht aber beim Speichern jetzt...

    Lulz: vllt ist es unvorteilhaft ein disposedes Bild zu speichern... :D
    Wie ist das eigentlich mit dem Image.Dispose? Muss man das machen um den Speicher frei zu bekommen, oder geht das automatisch, wenn die lokale Variable "ungültig" wird?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Sederic Enders“ ()

    ErfinderDesRades schrieb:

    machma das Disposen weg, dann kommt evtl. wieder der Fehler, dass die Datei noch gesperrt ist.
    Alter Latz, wenn du recht hast, dann bist du echt genial :D ich überleg scho wieder die ganze Zeit, wer das blockiert...

    Aber die Frage ist, wo kann ich disposen, weil ich ja das Bild speichern muss, aber das speichern u.U. auch schon blockiert werden kann...

    Was ich bis jetzt hab (der Pfad kann sich u.U. auch noch ändern, warum muss ich etz glaub net erklären):
    Spoiler anzeigen

    Quellcode

    1. string oldPath = sch.ImagePath2;
    2. Bitmap nImg = FileHandling.AdaptImage(new Bitmap(oldPath));
    3. string newPath = "blablaNeuerPfad :D ";
    4. sch.ImagePath2 = newPath;
    5. nImg.Save(newPath, System.Drawing.Imaging.ImageFormat.Png);
    6. nImg.Dispose(); //zu spät, wenn sich der Name nicht geändert hat...
    7. if (newPath != oldPath)
    8. System.IO.File.Delete(oldPath);
    Also etz hab ich mal ne Frage: Wie kann ich ein Bild bearbeiten und unter dem gleichen Namen speicher?!?!
    Das Programm blockiert sich doch dann automatisch selber, wenn es das Bild noch geöffnet hat...

    Mein Ansatz:

    Quellcode

    1. if (System.IO.File.Exists(PicturePath))
    2. {
    3. Bitmap bild = new Bitmap(PicturePath);
    4. if (bild != null)
    5. {
    6. Bitmap nimg = (Bitmap)Titelbild.Clone();
    7. bild.Dispose();
    8. if (File.Exists(PicturePath))
    9. File.Delete(PicturePath);
    10. nimg.Save(path, System.Drawing.Imaging.ImageFormat.Png);
    11. nimg.Dispose();
    12. }
    13. }
    Tu mal das Bild mit nem Stream öffnen und den dann schließen! Dann sollte es gehen. Mit Dispose habe ich immer in solchen Fällen schlechte Erfahrungen gemacht!
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Du bist der Chef :D Danke
    hab das hier gefunden...
    Spoiler anzeigen

    Der Code, um ein Bild in ein png bild umzuwandeln und zu speichern, würde dann so aussehen: (c#) :D

    Quellcode

    1. if (oldPath))
    2. {
    3. System.IO.FileStream oStream = new System.IO.FileStream(oldPath, System.IO.FileMode.Open);
    4. // Bitmap-Objekt mit den Daten aus dem Stream füllen
    5. Bitmap Img = new Bitmap(oStream);
    6. // Stream-Objekt und somit auch die Datei schließen
    7. oStream.Close();
    8. string newPath = DirectoryPath + "\\Bildname.png"; //oder wie mans halt braucht und hat...
    9. //wenn das Bild verwendet werden soll, kann man es hier oder nächste Zeile setzen
    10. Img.Save(newPath, System.Drawing.Imaging.ImageFormat.Png);
    11. Img.Dispose();
    12. //if (newPath != oldPath) //wenn man das alte Bild löschen will
    13. //System.IO.File.Delete(oldPath);
    14. }
    Danke :D
    Ja, also wenn der Code funzt... Sollte er eigentlich.

    Du musst halt folgendes beachten:

    - Bild im Stream öffnen
    - Stream schließen
    - Bild speichern

    Dann sollte es gehen! Selbst wenn du das Image freigibst mit Dispose , dann fliegt dir ne Exception um die Ohren.
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!: