Fehler: Der Index war außerhalb des Arraybereiches

  • VB.NET

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von fabianpr.

    Fehler: Der Index war außerhalb des Arraybereiches

    Hey Community,
    bin gerade an einem sehr komplexen Programm & der Projektfortschritt beläuft sich auf ca. 35%.
    Das Programm soll ein Textdokument einlesen & immer 3 Buchstaben [ASCII] in einen Pixel schreiben z.B [RGB: 212[Buchstabe1], 112[Buchs.2], 56[Buchst. 3]].
    In meinem Code für den "Server" tauchen allerdings immer wieder Fehler auf, die ich nicht genaustens lösen kann bzw. nur ändern kann, so dass eine andere Fehlermeldung kommt. Hier der mein aktueller Code [Fehlerhafte Zeile ist rot markiert]:

    VB.NET-Quellcode

    1. Imports FastGraphicsLib
    2. Public Class Form1
    3. Dim totalusedbytes As Integer = 0
    4. Dim totalpics As Integer = 0
    5. Dim ziel_id As String = "testziel"
    6. Dim Text1 As String = "abshfhsnfusfhsuhf1128374743838!hjhdfjdfh388734834hdfjhdfjf"
    7. Public Sub SetPixel(ByVal x As Integer, ByVal y As Integer, ByVal cl As Color)
    8. End Sub
    9. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    10. Dim newlength As Integer = Text1.Length - totalusedbytes
    11. If newlength >= 28500000 Then
    12. If totalpics = 0 Then
    13. routine(0, 28500000)
    14. Else
    15. 'Was passieren würde, wenn schon Bilder gezeichnet worden sind, aber immer noch genug Bytes
    16. 'in der Datei sind um ein "volles Picture" voll zu bekommen
    17. routine(totalusedbytes, (totalusedbytes + 28500000))
    18. End If
    19. Else
    20. 'Was passieren würde, wenn der Text bzw. die Datei weniger als 28,5Mil. Bytes enthält
    21. '[es wird automatisch ausgerechnet wieviel Pixel das Bild haben müsste um die "Niederigere Bytezahl"
    22. 'speichern zu können
    23. routine(totalusedbytes, Text1.Length)
    24. End If
    25. End Sub
    26. Public Sub routine(ByVal minlength As Integer, ByVal maxlength As Integer)
    27. Dim durchgang As Integer = 1
    28. Dim maxmin As Integer = maxlength - minlength
    29. Dim x As Single
    30. Dim c As Double
    31. Dim newbmp As Integer = maxmin / 3
    32. If Not newbmp = 28500000 Then
    33. c = Convert.ToDouble(newbmp)
    34. x = Math.Round(c)
    35. newbmp = x
    36. End If
    37. Dim img As FastGraphics = FastGraphics.FromBitmap(New Bitmap(newbmp, 1))
    38. For i As Integer = minlength To maxlength - 1 Step 3 '28,5 Mil.=9,5Mil.*3 [28,5M. ASCII-Zeichen passen in 3800x2500]
    39. Dim R As Integer = Convert.ToByte(Text1(i))
    40. Dim G As Integer = Convert.ToByte(Text1(i + 1))
    41. Dim B As Integer = Convert.ToByte(Text1(i + 2))
    42. Dim col As Color = Color.FromArgb(R, G, B)
    43. 'Pixel setzen
    44. img.SetPixel(durchgang, 1, col) 'Str(i) oder durchgang gibt die Zahl des "wievielten" Durchlauf's aus
    45. totalpics = totalpics + 1
    46. totalusedbytes = totalusedbytes + maxmin
    47. durchgang = durchgang + 1
    48. Next
    49. img.Bitmap.Save("C:/Users/******/" & minlength & "_" & maxlength & "_" & ziel_id & ".png")
    50. MsgBox("Congratulations! The application was successful! Thank you very much for taking part at our Alpha-Test!")
    51. End Sub
    52. End Class


    In dieser roten Zeile taucht immer wieder der Fehler
    :!: IndexOutOfRangeException wurde nicht behandelt
    Der Index war außerhalb des Arraybereiches :!: auf.

    Daraufhin versuchte ich das Problem zulösen, indem ich sogar praktischerweiße 4 Buchstaben in einer Farbe/Pixel speichern kann [Alpha, Rot, Grün, Blau] Dafür änderte ich die obere For|next-Schleife, sowie in der Source alle 28500000-Zahlen in 30000000-Zahlen:

    VB.NET-Quellcode

    1. For i As Integer = minlength To maxlength - 1 Step 4 '30 Mil.=7,5Mil.*4 [30M. ASCII-Zeichen passen in 7500000x1px]
    2. Dim A As Integer = Convert.ToByte(Text1(i))
    3. Dim R As Integer = Convert.ToByte(Text1(i + 1))
    4. Dim G As Integer = Convert.ToByte(Text1(i + 2))
    5. Dim B As Integer = Convert.ToByte(Text1(i + 3))
    6. Dim col As Color = Color.FromArgb(A, R, G, B)
    7. 'Pixel setzen
    8. img.SetPixel(durchgang, 1, col) 'Str(i) oder durchgang gibt die Zahl des "wievielten" Durchlauf's aus
    9. totalpics = totalpics + 1
    10. totalusedbytes = totalusedbytes + maxmin
    11. durchgang = durchgang + 1
    12. Next


    Selbst hier bekomme ich immer noch den gleichen Fehler [IndexOutOfRangeException.. Der Index war außerhalb..]

    Ich würde mich sehr freuen, wenn jemand Rat wüsste, wie ich das Problem lösen könnte. Ich bin mir sicher, es ist nur ein kleiner Fehler, aber ich hatte zu wenig Schlaf letzte Nacht, vielleicht erkenne ich ihn deswegen nicht :whistling:

    Achja, ich programmiere in Visual Basic Express 2011, falls das wichtig sein sollte^^
    bis dahin,..
    Fabian

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

    Du willst einen Text also als "Bild" kodieren?
    Witzige Idee. Nur der Ansatz ist schon komplett daneben ;)

    Neue Bitmap in der richtigen Größe anlegen, Bitlock, Text nach Bytearray, Bytearray nach Bitmapdata kopieren, Bitlock Ende. Done.
    Dauert vermutlich deutlich weniger als ne Sekunde. SetPixel hingegen ... schnarch.
    Deine Bitmap ist 1 Pixel hoch.

    VB.NET-Quellcode

    1. 'img.SetPixel(durchgang, 1, col)
    2. img.SetPixel(durchgang, 0, col)
    Die y-Koordinate ist Null-basiert.
    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!
    Okay, danke bis hierhin..
    @picoflop: Ich will dich ja nicht nerven, aber kannst du mir das an ein paar Snippetbeispielen erklären ?
    & das SetPixel ist nicht das aus der Bitmap-Klasse sondern das aus der FastGraphicsLib, aber wenn ich deine Worte richtig aufnehme, wäre dein Weg der schnellste, stimmts :D ?
    @RodFromGermany: Ou, das hatte ich garnicht gesehen^^, aber durch umändern gibt es immer noch den selben Fehler ;/

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

    fabianpr schrieb:

    die etwas "einfacher" sind



    bin gerade an einem sehr komplexen Programm


    Also ein sehr komplexes Programm, dass aber möglichst "einfache" (sprich BASIC Niveau von 1987?) Lösungen haben muss.

    Die Lösung mit ByteArray, Marshall etc IST einfacher als deine aktuelle "Lösung". Und schneller. Und sauberer.

    jvbsl schrieb:

    Aber nicht allzu viel

    Wolln mer mal benschen ... ?

    EDIT:
    done


    VB.NET-Quellcode

    1. Dim stp As New Stopwatch
    2. GC.Collect()
    3. stp.Start()
    4. Dim s As New String("A"c, 3000000)
    5. Dim sb() As Byte = System.Text.Encoding.ASCII.GetBytes(s)
    6. Dim b As New Bitmap(1000, 1000, System.Drawing.Imaging.PixelFormat.Format24bppRgb)
    7. Dim bm As System.Drawing.Imaging.BitmapData = b.LockBits(New Rectangle(0, 0, b.Width, b.Height), Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format24bppRgb)
    8. Dim ptr As IntPtr = bm.Scan0
    9. System.Runtime.InteropServices.Marshal.Copy(sb, 0, ptr, sb.Length)
    10. b.UnlockBits(bm)
    11. PictureBox1.Image = b
    12. stp.Stop()
    13. MessageBox.Show(stp.ElapsedMilliseconds)


    Im Schnitt 100ms. How schnell mit SetPixel?

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

    FastGraphicsLib - sollte ich die kennen?
    Ah, ja, ein Dings aus dem Showroom.
    Da weiß man ja eiglich nie, woran ein Fehler liegt - kannja immer auch ein Bug der Lib sein. Und auch das Posten über 3rd Party-dlls ist sehr beschränkt, dazu kann natürlich nur einer was sagen, der sich damit auskennt.
    Da muss ich meinem Vorposter recht geben. Ich kannte die Lib auch zuerst nicht, aber ein Skype-Kontakt hat sie mir empfohlen, weil er schon ein paar Mal damit gearbeitet hat. Anscheinend ist die Lib aber doch nicht "so" bugfrei, wie er meinte^^
    Gut, ich hab das jetzt drin mit Marshall.Copy etc..

    probieren geht über studieren :D,
    Fabian