Bild-Ausschnitte aus einem Bild

  • VB.NET
  • .NET (FX) 4.5–4.8

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

    Bild-Ausschnitte aus einem Bild

    Moin zusammen,

    ich möchte folgendes gerne machen:
    1.) Ich lade ein Bild in eine PictureBox mittels OpenFileDialog
    2.) Ich wähle mittels FolderBrowserDialog einen Ordner Pfad aus (zum speichern später)
    3.) Mit einem klick auf "Erstellen" soll dann das bild in der PictureBox auf die Größe 600x600px gebracht werden und dieses Bild soll dann 9 verschiedene teile besitzen

    Zu 1. habe ich das ganze so gelöst das es auch klappt:

    VB.NET-Quellcode

    1. OpenFileDialog1.Filter = "Bilder|*.jpg;*.png"
    2. OpenFileDialog1.FileName = ""
    3. Dim BildResult As DialogResult = OpenFileDialog1.ShowDialog()
    4. If BildResult = Windows.Forms.DialogResult.OK Then
    5. Dim BildName As String = OpenFileDialog1.FileName
    6. PictureBox1.Image = Image.FromFile(BildName)
    7. TextBox1.Text = BildName
    8. PublicBild = BildName 'PublicBild ist ganz oben mit "Dim PublicBild" vorhanden.
    9. End If


    Zu 2. habe ich das ganze so gelöst das es auch klappt:

    VB.NET-Quellcode

    1. Dim OrdnerResult As DialogResult = FolderBrowserDialog1.ShowDialog()
    2. If OrdnerResult = Windows.Forms.DialogResult.OK Then
    3. Dim OrdnerName As String = FolderBrowserDialog1.SelectedPath
    4. TextBox2.Text = OrdnerName
    5. PublicOrdner = OrdnerName 'PublicOrdner ist ganz oben mit "Dim PublicOrdner" vorhanden.
    6. End If


    Nun kommen wir zu Punkt 3. und da struggel ich ganz schön und komme auch mit Google irgendwie nicht weiter.
    Was ich geschafft habe ist das ausgewählte Bild schon mal auf die Maße 600x600px zu bringen und auch direkt zu speichern als bspw. "temp_img.jpg".
    Allerdings schaff ich nicht die Ausschnitte des Bildes 200x200px (von oben links angefangen) und 200x200px (bis unten rechts) = 9 Ausschnitte zu erstellen.

    Ich wäre da echt dankbar für jede hilfreiche Unterstützung.

    Lg
    @PlatinSecurity Du musst den betreffenden Ausschnitt der Quelle in ein neues Ziel malen.
    Sieh Dir dazu die Überladungen von Graphics.DrawImage() an, wo Ziel- und Quellkoordinaten angegeben werden können.
    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!
    Hey, ich hab mir das mal angeschaut und versucht zu verstehen.
    Jetzt hatte ich versucht folgendes zu machen für z.B. 3 Ausschnitte:

    VB.NET-Quellcode

    1. Dim BMP_Teil9 As New Drawing.Bitmap(200, 200)
    2. Dim BMP_Teil8 As New Drawing.Bitmap(200, 200)
    3. Dim BMP_Teil7 As New Drawing.Bitmap(200, 200)
    4. Dim GFX_Teil9 As Graphics = Graphics.FromImage(BMP_Teil9)
    5. Dim GFX_Teil8 As Graphics = Graphics.FromImage(BMP_Teil8)
    6. Dim GFX_Teil7 As Graphics = Graphics.FromImage(BMP_Teil7)
    7. GFX_Teil9.DrawImage(System.Drawing.Image.FromFile(My.Settings.SaveFolder & "\temp_img." & PublicBildFormatLoad), 0, 200, 200, 200)
    8. GFX_Teil8.DrawImage(System.Drawing.Image.FromFile(My.Settings.SaveFolder & "\temp_img." & PublicBildFormatLoad), 200, 200, 200, 200)
    9. GFX_Teil7.DrawImage(System.Drawing.Image.FromFile(My.Settings.SaveFolder & "\temp_img." & PublicBildFormatLoad), 400, 200, 200, 200)
    10. BMP_Teil9.Save(My.Settings.SaveFolder & "\bild9." & PublicBildFormatLoad)
    11. BMP_Teil8.Save(My.Settings.SaveFolder & "\bild8." & PublicBildFormatLoad)
    12. BMP_Teil7.Save(My.Settings.SaveFolder & "\bild7." & PublicBildFormatLoad)

    Die Bilder werden aber Schwarz.
    Wenn ich bsw.

    Quellcode

    1. GFX_Teil9.DrawImage(System.Drawing.Image.FromFile(My.Settings.SaveFolder & "\temp_img." & PublicBildFormatLoad), 0, 0, 200, 200)

    mache, dann macht er das ganze temp_img (600x600) nur in klein also 200x200
    @PlatinSecurity Probier mal so was, hab ich probiert:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim img As Image
    3. Using dlg = New OpenFileDialog
    4. If dlg.ShowDialog() <> DialogResult.OK Then
    5. Return
    6. End If
    7. img = Image.FromFile(dlg.FileName)
    8. End Using
    9. PictureBox1.Image = img
    10. Dim bmp = New Bitmap(100, 100)
    11. Using g = Graphics.FromImage(bmp)
    12. g.DrawImage(img, New Rectangle(0, 0, 100, 100), New Rectangle(0, 0, 100, 100), GraphicsUnit.Pixel)
    13. End Using
    14. PictureBox2.Image = bmp
    15. End Sub
    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!
    Mega... Es klappt.
    Hab es natürlich meinen wünschen (größe und positionen etc.) angepasst und so funktioniert es.

    Danke dir.
    Eine kleine Frage noch @RodFromGermany
    Wenn ich ein neues Bild auswähle nach dem ich das erste mal das gemacht habe,
    kommt der Fehler:

    System.Runtime.InteropServices.ExternalException (0x80004005): Allgemeiner Fehler in GDI+.
    bei System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
    bei System.Drawing.Image.Save(String filename, ImageFormat format)
    bei System.Drawing.Image.Save(String filename)
    bei Form1.Button3_Click(Object sender, EventArgs e) in C:\pfad\Form1.vb:Zeile 68.

    Bei Zeile 68 steht halt das

    VB.NET-Quellcode

    1. BMP.Save(My.Settings.SaveFolder & "\temp_img." & PublicBildFormatLoad)


    Habe schon ".Dispose()" versucht bei BMP und GFX aber das bringt irgendwie nichts.
    @PlatinSecurity Da müsstest Du mal den kompletten relevanten Code posten.
    Falls Du viel weglassen musst / willst, teste zunächst, ob der Ausschnitt den Effekt reproduziert.
    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!

    RodFromGermany schrieb:

    Da müsstest Du mal den kompletten relevanten Code posten.

    Also relevant ist in dem Moment nur

    VB.NET-Quellcode

    1. ​Dim BMP As New Drawing.Bitmap(612, 612)
    2. Dim GFX As Graphics = Graphics.FromImage(BMP)
    3. GFX.DrawImage(System.Drawing.Image.FromFile(PublicBild), 0, 0, PictureBox1.Width, PictureBox1.Height)
    4. Try
    5. BMP.Save(My.Settings.SaveFolder & "\temp_img." & PublicBildFormatLoad)
    6. Catch ex As Exception
    7. MsgBox(ex.ToString)
    8. End Try

    Weil dort bei

    VB.NET-Quellcode

    1. ​BMP.Save(My.Settings.SaveFolder & "\temp_img." & PublicBildFormatLoad)

    der Fehler kommt nach dem ich schon einmal das genutzt hab.

    Also um es kurz noch mal zu umschreiben:
    1. Ich starte das Programm.
    2. Ich kann bis dahin alles machen und es funktioniert bestens.
    3. Nun lade ich ein neues Bild
    4. Drücke wieder auf "Erstellen"
    5. Fehler
    @PlatinSecurity Gib mal Deiner Datei ein konkretes Format:

    VB.NET-Quellcode

    1. BMP.Save("c:\Temp\temp_img.png", System.Drawing.Imaging.ImageFormat.Png)
    Ist gesichert, dass die Größen der PictureBox und 612 x 612 ausreichen?
    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!

    RodFromGermany schrieb:

    Gib mal Deiner Datei ein konkretes Format

    Hab ich gemacht, hat sich aber vom Fehler her nichts getan.

    RodFromGermany schrieb:

    Ist gesichert, dass die Größen der PictureBox und 612 x 612 ausreichen?

    Ja. Daher kommt aber der Fehler auch nicht.

    Ich starte ja wie erwähnt das Programm und kann es einmal ohne Probleme richtig nutzen.
    Nachdem er 1 Bild mit 9 Ausschnitten erstellt hat, möchte ich aber z.B. noch ein Bild mit 9 Ausschnitten erstellen und wähle daher
    ein anderes Bild aus. Dann drücke ich wieder auf erstellen und der Fehler erscheint.
    @PlatinSecurity Das kann ich so nicht nachvollziehen.
    Poste mal so viel Code, dass damit bei mir dieser Fehler kommt.
    Teste das vorher bei Dir, damit ich nicht nochmal nachfragen muss.
    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!
    Danke dir für deine Mühe.
    Ich habe gerade eben das Problem wohl ausfindig machen können.

    Es lag daran, dass die selbe Datei schon in dem Zielordner war.
    Komisch das es erst beim zweiten mal passiert der Fehler und beim ersten mal die Dateien überschreiben.

    Habe einfach nun davor noch ein Ordner erstellen lassen mit

    VB.NET-Quellcode

    1. My.Computer.FileSystem.CreateDirectory(My.Settings.SaveFolder & "\" & NewOrdner)​

    Wo einfach der Zeitstempel und Datum benutzt wird.

    So speichert er immer alles in ein neuen Ordner.

    PlatinSecurity schrieb:

    Ich habe gerade eben das Problem wohl ausfindig machen können.
    Nö, das isses nich.
    Dies funktioniert problemlos:

    VB.NET-Quellcode

    1. Dim PublicBild As String = "C:\Temp\img.jpg"
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. Dim BMP As New Bitmap(PublicBild)
    4. BMP.Save("c:\Temp\temp_img.png", System.Drawing.Imaging.ImageFormat.Png)
    5. BMP.Save("c:\Temp\temp_img.png", System.Drawing.Imaging.ImageFormat.Png)
    6. BMP.Save("c:\Temp\temp_img.png", System.Drawing.Imaging.ImageFormat.Png)
    7. BMP.Save("c:\Temp\temp_img.png", System.Drawing.Imaging.ImageFormat.Png)
    8. BMP.Save("c:\Temp\temp_img.png", System.Drawing.Imaging.ImageFormat.Png)
    9. End Sub
    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!
    Auch wenn du noch mal auf den Button drückst?
    Beim ersten mal klappt das bei mir ja auch ... dann überschreibt er einfach die vorhandene Datei.
    Aber wenn ich noch mal auf den Button drücke löst er den Fehler aus. Warum auch immer.
    Die Form mit dem Ordner erstellen als Zeitstempel sieht aktuell aber auch besser aus. (finde ich)

    PlatinSecurity schrieb:

    Auch wenn du noch mal auf den Button drückst?
    Ja.
    Aus Speichergründen machen wir

    VB.NET-Quellcode

    1. Using BMP As New Bitmap(PublicBild)
    2. BMP.Save("c:\Temp\temp_img.png", System.Drawing.Imaging.ImageFormat.Png)
    3. BMP.Save("c:\Temp\temp_img.png", System.Drawing.Imaging.ImageFormat.Png)
    4. BMP.Save("c:\Temp\temp_img.png", System.Drawing.Imaging.ImageFormat.Png)
    5. BMP.Save("c:\Temp\temp_img.png", System.Drawing.Imaging.ImageFormat.Png)
    6. BMP.Save("c:\Temp\temp_img.png", System.Drawing.Imaging.ImageFormat.Png)
    7. End Using
    und ich kann auf dem Button Klavier spielen.
    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!
    Komisch. Hab es auch mal mit einer neuen Form versucht und da geht es auch wie bei dir.
    Nur ich hab es mit dem erstellen eines Ordners gelöst.

    Danke dir noch mal dennoch für deine tolle Bemühung.