Bildreparatur (keine Vorschau bei Windows, zur Programmlaufzeit fliegt eine Exception)

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

Es gibt 27 Antworten in diesem Thema. Der letzte Beitrag () ist von Bartosz.

    Bildreparatur (keine Vorschau bei Windows, zur Programmlaufzeit fliegt eine Exception)

    Hallo zusammen,

    ich hätte eine Frage: ich habe ein jpg-Bild im Bestand, dessen Vorschau bei Windows nicht angezeigt wird. Rechtsklick -> Öffnen mit -> Windows-Fotoanzeige bringt nichts, es kommt die Fehlermeldung, dass es das falsche Format hat. Nur mit Picasa 3 geht es zu öffnen. Da habe ich mir gedacht, wenn Picasa das kann, dann muss ich das auch schaffen.

    Mit meiner üblichen Pfadsuche (siehe Code) heißt es "ungültiger Parameter".

    VB.NET-Quellcode

    1. Private Sub ScanDirectory(ByVal Directory1 As IO.DirectoryInfo)
    2. Dim Liste_mit_Formaten = New List(Of String) From {".jpg", ".png", ".jpeg", ".bmp"}
    3. For Each Directory In Directory1.EnumerateDirectories
    4. Try
    5. For Each File In Directory.EnumerateFiles
    6. Try
    7. If Liste_mit_Formaten.Contains(File.Extension.ToLower(New CultureInfo("de-DE"))) Then
    8. Dim v_P As String = Directory1.ToString + "\" + Directory.ToString + "\" + File.ToString
    9. Try 'Try/Catch, weil es (selten) vorkommen kann, dass Bilder kaputt sind
    10. Using BMP1 As New Bitmap(v_P) 'Hier fliegt die Exception
    11. End Using
    12. Catch ex As System.ArgumentException
    13. TextBox_Info.Text = "Datei kaputt / Wird nicht unterstützt " & v_P
    14. Application.DoEvents()
    15. Catch ex2 As System.NotSupportedException
    16. TextBox_Info.Text = "System.NotSupportedException: Fehler mit Pfad!"
    17. Application.DoEvents()
    18. End Try
    19. End If
    20. Catch Ex As UnauthorizedAccessException
    21. ScanDirectory(Directory)
    22. End Try
    23. Next
    24. Catch Ex As UnauthorizedAccessException
    25. TextBox_Info.Text = "Verboten"
    26. End Try
    27. Next
    28. End Sub


    Der Fehler im Stacktrace sagte etwas von System.Drawing.Bitmap..ctor. Das googelte ich und fand diesen Thread
    stackoverflow.com/questions/14…bitmap-ctor-stream-stream

    Derjenige hat sich anscheinend alle Bytes binär eingelesen und es dann zum Image umgewandelt. Das wollte bei mir nicht kompilieren. Ich musste erstmal allerhand umbauen, weil der Kompiler

    VB.NET-Quellcode

    1. Request.Files(CInt(0)).ContentLength)
    nicht mochte. Dann sah es so aus:

    VB.NET-Quellcode

    1. Private Sub Bild_reparieren(ByVal Pfad_R As String)
    2. Dim fileData As Byte() = Nothing
    3. Using binaryReader As System.IO.BinaryReader = New System.IO.BinaryReader(System.IO.File.Open(Pfad_R, System.IO.FileMode.Open)) '(Request.Files(0).InputStream)
    4. fileData = binaryReader.ReadBytes(CInt(binaryReader.BaseStream.Length)) 'Request.Files(CInt(0)).ContentLength)
    5. Debug.WriteLine("Reparatur")
    6. End Using
    7. Dim imageConverter As ImageConverter = New System.Drawing.ImageConverter()
    8. Try
    9. Dim image As System.Drawing.Image = TryCast(imageConverter.ConvertFrom(fileData), System.Drawing.Image) 'hier wieder derselbe Fehler
    10. Using FBSD2 As New CommonSaveFileDialog()
    11. FBSD2.Title = "Repariertes Bild wo speichern?"
    12. Dim item1 As CommonFileDialogFilter = New CommonFileDialogFilter("Bitmap", ".bmp")
    13. FBSD2.Filters.Add(item1)
    14. FBSD2.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
    15. FBSD2.RestoreDirectory = True
    16. If FBSD2.ShowDialog() = CommonFileDialogResult.Ok Then
    17. Pfad_speichern = System.IO.Path.GetFullPath(FBSD2.FileName)
    18. image.Save(Pfad_speichern, System.Drawing.Imaging.ImageFormat.Bmp)
    19. End If
    20. End Using
    21. Catch ex As System.ArgumentException
    22. Return
    23. End Try
    24. End Sub

    Selber Fehler.

    Was kann ich tun?
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.

    VB.NET-Quellcode

    1. Imports System
    2. Imports System.IO
    3. Module Program
    4. Sub Main(args As String())
    5. Dim buffer(1) As Byte
    6. Using fS As New FileStream("e:\ftp\IMG_20200313_010149.jpg", FileMode.Open, FileAccess.Read)
    7. fS.Read(buffer, 0, buffer.Length)
    8. End Using
    9. If buffer.SequenceEqual({&HFF, &HD8}) Then
    10. Console.WriteLine("JPG-File")
    11. Else
    12. Console.WriteLine("No JPG-File")
    13. End If
    14. End Sub
    15. End Module


    Die ersten 2 Bytes sind laut de.wikipedia.org/wiki/JPEG_File_Interchange_Format die SOI (Start Of Image) Kennung... Musst Dir die Header-Beschreibung mal anschauen und selbst rausfinden, was man alles zur genauen Identifikation braucht.....
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    @SpaceyX Danke für den Code. Es ist tatsächlich kein Jpg. Und jetzt bin ich ratlos...
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.
    RI (82, 73 als dezimal) keine Ahnung, was das ist. Googlen brachte mir nix

    ###
    Edit: Bei Picasa 3 -> Tools -> Optionen -> Dateitypen steht auch nichts von RI
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.
    0x52 0x49 (Dezimal: 82 73) ist wohl ein webp-Image.

    en.wikipedia.org/wiki/List_of_file_signatures

    Lies Dir mal den letzten Beitrag hier durch: askubuntu.com/questions/606735…-sudden-when-using-chrome Soweit ich weiß, kann Windows diese Dateien nicht mit Boardmitteln anzeigen...
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o
    Ok, das heißt, da hat der Download abgebrochen und es wurden nur Chunks hinterlassen. Was hältst du davon, wenn ich gleich mal ausprobier, in den Pfad statt ".jpg" einfach ".webp" zu schreiben..Moment..

    ###Edit
    @Bluespide zuu spät gesehen.

    ####Edit 2

    So, ich habe bisher Folgendes:

    VB.NET-Quellcode

    1. Private Sub Bild_reparieren(ByVal Pfad_R As String)
    2. Dim buffer(1) As Byte
    3. Using fS As New FileStream(Pfad_R, FileMode.Open, FileAccess.Read)
    4. fS.Read(buffer, 0, buffer.Length)
    5. End Using
    6. If buffer.SequenceEqual({&HFF, &HD8}) Then 'JPG
    7. Console.WriteLine("JPG-File")
    8. Else
    9. Console.WriteLine("No JPG-File")
    10. End If
    11. If buffer.SequenceEqual({&H42, &H4D}) Then 'BMP
    12. Console.WriteLine("BMP-File")
    13. Else
    14. Console.WriteLine("No BMP-File")
    15. End If
    16. If buffer.SequenceEqual({&H52, &H49}) Then 'RI (82, 73)
    17. Console.WriteLine("RI-File (.webp)")
    18. Dim neue_Endung As String = Pfad_R.Substring(0, Pfad_R.LastIndexOfAny(CType(".", Char()))) & ".webp"
    19. Using image As Bitmap = WebPFormat.LoadFromStream(New FileStream(neue_Endung, FileMode.Open, FileAccess.Read))
    20. image.Save(neue_Endung, Imaging.ImageFormat.Png)
    21. End Using
    22. Else
    23. Console.WriteLine("No RI-File (.webp)")
    24. End If


    WebPFormat kreidet er mir noch an. Kann man sich einfach gefahrlos eine libwebp.dll laden?



    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Bartosz“ ()

    @Bartosz Hole Dir den IrfanView, der stellt allein fest, dass es eine falsche Extension ist und schlägt das Umbenennen der Datei vor.
    Feddich.
    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 alles gut, Picasa und GIMP tun's ja auch :) Dachte nur, ich programmier mal wieder n bisschen ;)
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.
    @Bartosz Probierma das WPF-Set:

    VB.NET-Quellcode

    1. 'Verweis: WindowBase. PresentationCore
    2. Imports System.Windows.Media.Imaging
    3. Imports System.IO
    4. '################
    5. Using fs As New FileStream(PFAD_ZU_DEINER_DATEI, FileMode.Open, FileAccess.Read, FileShare.Read), ms As New MemoryStream
    6. Dim dec = BitmapDecoder.Create(fs, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None)
    7. Dim enc As New BmpBitmapEncoder
    8. enc.Frames.Add(BitmapFrame.Create(dec.Frames(0)))
    9. enc.Save(ms)
    10. Me.PictureBox1.Image = New Bitmap(ms)
    11. End Using

    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 Bei

    VB.NET-Quellcode

    1. Dim dec = BitmapDecoder.Create(fs, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None)
    kommt diesmal eine System.NotSupportedException. Es wurde keine passende Imagingkomponente zum Abschließen dieses Vorgangs gefunden. Innere Ausnahme: COMException: Die Komponente wurde nicht gefunden

    PS: habe noch über NuGet "WindowsBase" hinzufügen müssen, ist das relevant?
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.
    Ich gaube, da habe ich mich blöd ausgedrückt, sorry. Den Verweis hab ich vorher schon hinzugefügt, trotzdem kam der Fehler.
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.
    @Bartosz Das ganze funktioniert bei mir augenblicklich.
    Die beiden Verweise (WindowBase, PresentationCore), dieser Code:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.Windows.Media.Imaging
    2. Imports System.IO
    3. Public Class Form1
    4. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    5. Using fs As New FileStream("C:\Temp\Image 404.jpg", FileMode.Open, FileAccess.Read, FileShare.Read), ms As New MemoryStream
    6. Dim dec = BitmapDecoder.Create(fs, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None)
    7. Dim enc As New BmpBitmapEncoder
    8. enc.Frames.Add(BitmapFrame.Create(dec.Frames(0)))
    9. enc.Save(ms)
    10. Me.PictureBox1.Image = New Bitmap(ms)
    11. End Using
    12. End Sub
    13. End Class
    Und mit einem Bild mit falscher Extension: PNG statt JPG.
    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, dass es bei mir nicht läuft... Ich habe in anderen Foren geelsen, dass man Windows Imaging Component braucht, und dass diese automatisch bei meinem windows 8.1 64 bit installiert ist. Also es müsste laufen -.-
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.
    @Bartosz Dieser Code funktioniert bei mir unter W7-32, W7-64 und W10-64, ab FW 4.
    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 ok... aber du hast auch PNG statt JPG genommen, bei mir liegt ja dieses .webp vor ..
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.