Solving graphical errors

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

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von NoIde.

    Solving graphical errors

    Hi,

    ich habe hier ein ziemlich vertracktes Problem.

    Ich habe ein VB Programm ... in der "produktiven" Version erhalte ich (wiederholbar) einen Fehler. Wenn ich das Programm mit den gleichen Daten in der Debug Version aufrufe, dann tritt der Fehler NICHT auf.

    Anbei die Fehlermeldung der produktiven Version.

    Gemäß der Anleitung habe ich jetzt versucht den JIT Debugger in der produktiven Version zu aktivieren und dazu eine Zeile in die App.config eingefügt. (s. Anlage)

    Aber das Ergebnis ist das gleiche. Ich erhalte nach wie vor nur das "Continue" pop up window ... und das hilft mir nicht viel weiter ...

    Kann mir jemand sagen, wie ich den Fehler "fangen" kann ?

    LG
    Peter
    Bilder
    • s 2018-08-06 13-55-465.jpg

      35,57 kB, 438×286, 83 mal angesehen
    • s 2018-08-06 13-57-431.jpg

      25,47 kB, 438×284, 79 mal angesehen
    • s 2018-08-06 13-59-515.jpg

      46,59 kB, 848×275, 80 mal angesehen

    Peter329 schrieb:

    Kann mir jemand sagen, wie ich den Fehler "fangen" kann ?
    Den Jit-Eintrag brauchst Du nicht.
    Füge der *.Exe die *.PDB hinzu (beides aus dem Release-Verzeichnis) => sollte einen StackTrace bringen.
    Oder
    Aktiviere die Anwendungsereignisse:
    Projekt->Eigenschaften->Anwendung
    => Anwendungsereignisse anzeigen
    links: MyApplication-Ereignisse
    rechts: UnhandledException
    und dann die Events auswerten, StackTrace ausgeben.
    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!
    ok ... jetzt bin ich ein Stück weiter gekommen.

    Ich lade einen .ico file in eine Bitmap. Diese Bitmap lade ich anschließend in eine PictureBox

    VB.NET-Quellcode

    1. Try
    2. Using fs As New FileStream(fileRealObject, FileMode.Open) 'Using is required to release lock on file
    3. copyBitmap = New Bitmap(fs)
    4. End Using
    5. Catch ex As Exception 'Cannot display picture
    6. MessageBox.Show("grafError: " & fileRealObject) '***TEST***
    7. copyBitmap = errorBitmap 'Display error picture
    8. myPicturebox.SizeMode = PictureBoxSizeMode.CenterImage
    9. myPicturebox.BackColor = Color.LightGray 'Error frame background color
    10. End Try
    11. myPicturebox.Image = copyBitmap 'Load display or error picture


    Das klappt auch für die meisten Icons. Aber ein Icon kann offensichtlich nicht geladen werden. Die Picture Box zeigt ein X-Image - dieses Bild habe ich in meinem Programm nicht definiert ! (s. Anhang)

    Obwohl da offensichtlich ein Fehler passiert, rennt das Programm im DEBUG Mode problemlos durch. (Andere Fehler werden angezeigt!)

    In der "Produktionsversion" tritt dann bei diesem Icon aber genau der beschriebene Laufzeitfehler auf.

    Überigens: weder im DEBUG noch in der Productionsversion wird der Catch-Block angesprungen !

    Wenn ich den .ico File mit Doppelclick öffne, wird das Icon vollkommen problemlos angezeigt !

    Ich bin ratlos ! Kann mir jemand helfen ?

    LG
    Peter
    Bilder
    • s 2018-08-06 16-04-065.jpg

      6,4 kB, 182×184, 244 mal angesehen

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

    Peter329 schrieb:

    dieses Bild habe ich in meinem Programm nicht definiert
    Das ist ein Bild, wenn beim Laden oder Anzeigen seitens einer .Image-Property intern eine Exception kam.
    Zunächst machst Du sdas so:

    VB.NET-Quellcode

    1. Using fs As New FileStream(fileRealObject, FileMode.Open)
    2. If myPicturebox.Image IsNot Nothing Then
    3. myPicturebox.Image.Dispose()
    4. End If
    5. myPicturebox.Image = New Bitmap(fs)
    6. End Using
    und ggf. drum herum noch ein Try / Catch, um genau dies abzufangen.
    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!
    Also ... ich habe jetzt ein Testprojekt erstellt, mit dem ich die Sache nachstellen kann.

    Calendar.ico ist ein "gutes" Icon.
    Calculator.ico ist ein Icon das Probleme verursacht.


    VB.NET-Quellcode

    1. Imports System.IO
    2. Public Class Form1
    3. Dim fileRealObject1 As String = "......\Calendar.ico" 'Good icon
    4. Dim fileRealObject2 As String = "......\Calculator.ico" 'Icon causing problem
    5. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    6. LoadPicture(fileRealObject1)
    7. End Sub
    8. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    9. LoadPicture(fileRealObject2)
    10. End Sub
    11. Private Sub LoadPicture(FileRealObject As String)
    12. Dim copyBitmap As Bitmap = Nothing 'Initialize display picture
    13. If myPictureBox.Image IsNot Nothing Then
    14. myPictureBox.Image.Dispose()
    15. End If
    16. Try
    17. Using fs As New FileStream(FileRealObject, FileMode.Open) 'Using is required to release lock on file
    18. copyBitmap = New Bitmap(fs)
    19. End Using
    20. myPictureBox.Image = copyBitmap 'Load display picture
    21. Catch ex As Exception 'Cannot display picture
    22. MessageBox.Show("grafError: " & FileRealObject) 'trap exception
    23. End Try
    24. End Sub
    25. End Class


    Was mir auffällt, nachdem ich das fehlerhafte Icon versucht habe zu laden, kann man das "gute" Icon auch nicht mehr laden.

    Egal was ich klicke ... die Catch Routine wird nicht angesprungen, d.h. alle Befehle laufen ohne Fehler durch.

    Irgendwie verstehe ich nicht, was da schief läuft.

    LG
    Peter
    Dateien
    • Calendar.ico

      (1,66 kB, 74 mal heruntergeladen, zuletzt: )
    • Camera.ico

      (84,7 kB, 79 mal heruntergeladen, zuletzt: )
    Also mein Verzeichnis enthält über 250 ions ... und bis auf 4 icons werden alle korrekt angezeigt.

    Die Routine verwende ich auch um .png, .jpg et. Files anzuzeigen ... und auch da funktioniert die Sache einwandfrei. Ich würde jetzt ungern für .ico files eine eigene Routine schreiben ...
    Das betroffene Camera-Icon enthält mehrere Auflösungen, bis hin zu 256x256. Ich tippe darauf, dass das das Problem ist. Nachdem ich die 32x32-Auflösung extrahiert und in eine eigene Datei gehauen hate, funktionierte es.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Peter329 Also:
    Zunächst heißt die Calculator.ico => Camera.ico.
    Öffne beide Dateien nacheinander im IrfanView und Du erkennst:
    Calendar.ico (1662 Byte) enthält genau ein Bild, was geladen werden kann.
    Camera.ico (84704 Byte) enthält 13 Bilder, und da kommt die Bitmap-Instanz schon mal ins Wanken.

    Mit dem Tipp von @Gonger96 sieht das dann so aus:

    VB.NET-Quellcode

    1. Private Sub LoadPicture(FileRealObject As String)
    2. Dim copyBitmap As Bitmap = Nothing 'Initialize display picture
    3. If myPictureBox.Image IsNot Nothing Then
    4. myPictureBox.Image.Dispose()
    5. End If
    6. Try
    7. Using fs As New FileStream(FileRealObject, FileMode.Open) 'Using is required to release lock on file
    8. If FileRealObject.ToLower().EndsWith(".ico") Then
    9. Dim ico = New Icon(fs)
    10. copyBitmap = ico.ToBitmap()
    11. Else
    12. copyBitmap = New Bitmap(fs)
    13. End If
    14. End Using
    15. myPictureBox.Image = copyBitmap 'Load display picture
    16. Catch ex As Exception 'Cannot display picture
    17. MessageBox.Show("grafError: " & FileRealObject) 'trap exception
    18. End Try
    19. 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!

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

    Yeheyyy ... na, da habt ihr ja das Problem EXAKT gefunden ... Jetzt werden alle .ico files aufgelöst ... DANKE !

    Aber ...

    ... aber es gibt leider einen Wermutstropfen. Der file Clock.ico führt jetzt zu einer Exception !

    Wenn ich DIESEN File jedoch mit der "alten" Methode copyBitmap = New Bitmap(fs)auflöse, dann funktioniert die Sache.

    Ich hoffe, ihr könnt mir das erklären und ein Rat geben, wie ich das jetzt noch lösen kann !
    Bilder
    • s 2018-08-06 20-33-421.jpg

      93,01 kB, 1.285×484, 72 mal angesehen
    Dateien
    • clock.ico

      (33,59 kB, 78 mal heruntergeladen, zuletzt: )
    Ich könnte mir vorstellen, dass das Icon einen Bitmapframe hat. ToBitmap eiert dann einfach alle Pixel durch und kopiert diese. Dabei kommt dann wahrscheinlich die Exception. Ich könnte mit vorstellen das dein Icon nicht i.O. ist. Probiere mal ob du das Icon per Drawicon zeichnen kannst.
    @Peter329 Das ist eine sehr merkwürdige Datei.
    Der IrfanView kann sie problemlos lesen.
    Wenn Du die Extension dieser Datei änderst: BMP, JPG, TIF, kann sie der IrfanView ebenfalls problemlos lesen, ohne dass er die Extension anmeckert!
    Ein "richtiges" Icon mit falscher Extension kann der IrfanView nicht einlesen.
    ====
    Gib dieser Datei die Extension BMP und der Code liest sie ein. :thumbsup:
    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!
    Ich bestätige: Laut Dateiinhalt (man öffne die Datei per Editor) ist das wohl eigentlich ne PNG-Datei (mit etwas komischem Header), die nur umbenannt wurde.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    mit etwas komischem Header


    Guggst du:
    fileformats.wikia.com/wiki/Icon

    Bei Icons werden die 256x256 Grossen Bilder komplett, also nicht nur die Pixeldaten in die Datei gepackt, daher sind die Magic bytes des PNG erkennbar.

    Vllt. kommt die Exception weil nur 1 Bild im Icon ist?

    @RodFromGermany Keine merkwürdige Datei, nur ein Icon mit nur einem 256x256 grossen PNG-Bild.
    Bilder
    • Unbenannt.jpg

      333,99 kB, 1.263×812, 76 mal angesehen
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „NoIde“ ()

    Also erst mal herzlichen Dank,dass ihr euch mit meinem vertrackten Problem befasst habt. Ich habe jetzt eine LÖSUNG für mein Problem gefunden. Aber erst mal zu euren Kommentaren:

    Jau, "clock.ico" ist aus einer .png Datei entstanden. Mein IconEditor arbeitet da irgendwie nicht so ganz sauber. Trotzdem stört sich daran NIEMAND außer der .toBitmap Function. Das Icon funktioniert, man kann es sich angucken, editieren ...

    Wie ihr vielleicht verstanden habt, schreibe ich hier eine "Tile Preview" Routine. Dabei hab ich jetzt noch ein Problem mit "animiated GIFs" .... auch da scheitert die Anweisung copyBitmap = New Bitmap(fs)

    Ich habe aber jetzt eine Lösung gefunden, die ALLE Probleme zu beheben scheint:

    VB.NET-Quellcode

    1. Dim bytData(-1) As Byte 'Allocate empty byte array
    2. bytData = My.Computer.FileSystem.ReadAllBytes(fileRealObject) 'Get object as byte array
    3. Dim converter As TypeConverter = TypeDescriptor.GetConverter(GetType(Bitmap))
    4. copyBitmap = DirectCast(converter.ConvertFrom(bytData), Bitmap) 'Convert byte array to bitmap


    Die verbasselte clock.ico wird angezeigt, ebenso wie die große camera.ico und auch mein animated.gif schnuckelt munter vor sich hin ... :) Bisher habe ich keinen einzigen Fehler entdecken können ! Auch keine Laufzeitfehler !

    Die Sache scheint sogar einigermaßen schnell zu laufen ... 1000 images werden in knapp 10 Sekunden aufbereitet. Und das kommt ja nicht alle Tage vor.

    Jetzt würde mich interessieren, was ihr dazu meint. Vielleicht kann man das ja noch verbessern.

    LG
    Peter

    Peter329 schrieb:

    My.Computer.FileSystem.ReadAllBytes


    Wie wäre es mit IO.File.ReadAllBytes?

    Peter329 schrieb:

    Mein IconEditor arbeitet da irgendwie nicht so ganz sauber.


    Das Icon ist korrekt. Ich würde fast darauf wetten, wenn du noch weitere grössen(Bilder) hinzufügst, das dir keine Exception um die Ohren fliegen würde.
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „NoIde“ ()

    NoIde schrieb:

    Keine merkwürdige Datei
    Dies ist schon merkwürdig:

    RodFromGermany schrieb:

    Wenn Du die Extension dieser Datei änderst: BMP, JPG, TIF, kann sie der IrfanView ebenfalls problemlos lesen, ohne dass er die Extension anmeckert!

    @Peter329 Mit der WPF-Funktionalität liest Du alle Deine Dateien ein, ohne die Extension checken zu müssen, hab ich auch so implementiert.
    Da bekommst Du auch ne korrekte Meldung, wenn das 16BPP-Bilder sind.
    Spoiler anzeigen

    C#-Quellcode

    1. Verweise:
    2. PresentationCore
    3. PresentationFramework
    4. System.Xaml
    5. WindowsBase
    6. using System;
    7. using System.Diagnostics;
    8. using System.IO;
    9. using System.Runtime.InteropServices;
    10. using System.Windows;
    11. using System.Windows.Media;
    12. using System.Windows.Media.Imaging;
    13. /// <summary>
    14. /// Reads an image from disk and converts it to 16 BPP grey pixel data
    15. /// </summary>
    16. /// <param name="fileName">path and name of the file</param>
    17. /// <param name="values">memory to store the image</param>
    18. /// <param name="width">out: width of the image</param>
    19. /// <param name="height">out: height of the image</param>
    20. /// <returns>Success</returns>
    21. public static bool ReadPictureGrey16(string fileName, out ushort[] values, out int width, out int height)
    22. {
    23. values = null;
    24. width = 0;
    25. height = 0;
    26. if (string.IsNullOrEmpty(fileName))
    27. {
    28. Debug.Assert(false, "Path is empty");
    29. return false;
    30. }
    31. // 16 BPP *.BMP würde sonst zu PixelFormat.Format32bppRgb konvertiert
    32. if (fileName.ToLower().EndsWith(".bmp"))
    33. {
    34. BmpHeader header;
    35. FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
    36. using (BinaryReader br = new BinaryReader(fs))
    37. {
    38. header = new BmpHeader(br);
    39. }
    40. // Sonderbehandlung: Mono 16 BPP
    41. if (header.BitDepth == 16)
    42. {
    43. BmpGray16 bmp = new BmpGray16();
    44. bmp.ReadImage(fileName);
    45. width = header.Width;
    46. height = header.Height;
    47. // Speicher für das Bild
    48. values = new ushort[header.Width * header.Height];
    49. int i = 0;
    50. for (int y = 0; y < header.Height; y++)
    51. {
    52. for (int x = 0; x < header.Width; x++)
    53. {
    54. values[i] = bmp.ImageData[x, y];
    55. i++;
    56. }
    57. }
    58. return true;
    59. }
    60. }
    61. using (Stream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
    62. {
    63. BitmapFrame bmp = null;
    64. try
    65. {
    66. BitmapDecoder decoder = null;
    67. decoder = BitmapDecoder.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);
    68. bmp = decoder.Frames[0];
    69. }
    70. catch
    71. {
    72. // not supported format
    73. return false;
    74. }
    75. width = bmp.PixelWidth;
    76. height = bmp.PixelHeight;
    77. int stride = bmp.PixelWidth;
    78. // Speicher für das Bild
    79. values = new ushort[height * width];
    80. // bmp.Format ist kein enum
    81. if (bmp.Format == PixelFormats.Gray16)
    82. {
    83. bmp.CopyPixels(values, stride * 2, 0);
    84. }
    85. else if (bmp.Format == PixelFormats.Gray8 ||
    86. bmp.Format == PixelFormats.Indexed8)
    87. {
    88. // 8 BPP-Formate werden explizit als solche eingelesen
    89. byte[] pixels8 = new byte[bmp.PixelHeight * bmp.PixelWidth];
    90. bmp.CopyPixels(pixels8, stride, 0);
    91. // convert 8 BBP to 16 BBP
    92. for (int i = 0; i < values.Length; i++)
    93. {
    94. values[i] = pixels8[i];
    95. }
    96. }
    97. else
    98. {
    99. // 16 BPP *.bmp landet hier
    100. // Alle anderen Formate werden explizit nach 16 BPP Grau konvertiert
    101. FormatConvertedBitmap newImage = new FormatConvertedBitmap(bmp, PixelFormats.Gray16, null, 0.0);
    102. newImage.CopyPixels(values, stride * 2, 0);
    103. newImage = null;
    104. }
    105. return true;
    106. }
    107. }
    Diese Prozedur liest alle Bilder und gibt ein UShort-16BPP-Array zurück.
    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:

    Dies ist schon merkwürdig:


    Ja. Allerdings liegt es wohl an IrfanView.

    Mit diesem Icon sollte es genau so sein:


    Edit: @RodFromGermany Ich habe festgestellt, das Irfanview bei keinem Icon meckert wegen einer falschen extension, solange ein 256x256 grosses Bild drin ist, da bei dieser grösse die ganze Bild-Datei in der Icon-Datei drin ist, nicht nur die Pixeldaten, parst IV wohl diesen PNG Header.
    Dateien
    • 1.ico

      (2,66 kB, 67 mal heruntergeladen, zuletzt: )
    Cloud Computer? Nein Danke! Das ist nur ein weiterer Schritt zur totalen Überwachung.
    „Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.“
    Benjamin Franklin

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „NoIde“ ()