Bild mit über 10 GP

  • VB.NET

Es gibt 51 Antworten in diesem Thema. Der letzte Beitrag () ist von BjöNi.

    Schau dir evtl auch das mal an: Mip-Mapping
    Was du hier speicherst, sind halt Rohdaten, keine z.B. PNGs, d.h. die Datei wird extrem aufgebläht.
    Er könnte natürlich auch eine Farbtabelle anlegen. Je nachdem, wie seine Bilder aussehen, sieht man das auch gar nicht, wenn nur zum Beispiel 256 Farben genutzt werden

    Skybird schrieb:

    Das sind ja Ubisoftmethoden hier !

    @Artentus:, @vb-checker:, @Bluespide::
    Ich habs gestern völlig verpeilt, aus irgendeinem Grund war ich der Meinung, dass 10.000px * 10.000px = 1MP, lol. Also: Eine Bitmap crasht ja schon bei weniger als hundert Megapixel.

    @~blaze~::
    Ich glaube, ich habe deinen Post (sogar ;)) verstanden, aber ich habe ehrlich gesagt keinen Bock, das Rad neu zu erfinden. Wenn man die Dateien weitergeben will, kann man ja den ganzen Ordner (vom Programm aus) zippen.

    @vb-checker: Post #21:
    Hier gilt das gleiche - die Dateien können meinetwegen in einem Ordner sein, das reicht mir vollkommen.

    @vb-checker: Post #19:
    Also derzeit sieht mein Code so aus:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private startpos As Point
    3. Private d As Integer = 0
    4. Private r As Integer = 0
    5. Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
    6. startpos = e.Location
    7. End Sub
    8. Private Sub Form1_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
    9. d -= (e.X - startpos.X) \ CInt(zoom.Value)
    10. r -= (e.Y - startpos.Y) \ CInt(zoom.Value)
    11. Invalidate()
    12. End Sub
    13. Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    14. If e.ClipRectangle.Location <> New Point(0, 0) Then
    15. Invalidate()
    16. Return
    17. End If
    18. For x As Integer = 0 To e.ClipRectangle.Width \ CInt(zoom.Value)
    19. For y As Integer = 0 To e.ClipRectangle.Height \ CInt(zoom.Value)
    20. If IO.File.Exists("...Ordner..." & (x + d).ToString & "-" & (y + r).ToString & ".png") Then
    21. Using img As Image = Image.FromFile("...Ordner..." & (x + d).ToString & "-" & (y + r).ToString & ".png")
    22. e.Graphics.DrawImage(img, New Rectangle(x * CInt(zoom.Value), y * CInt(zoom.Value), CInt(zoom.Value), CInt(zoom.Value)))
    23. End Using
    24. End If
    25. Next
    26. Next
    27. End Sub
    28. Private Sub zoom_ValueChanged(sender As Object, e As EventArgs) Handles zoom.ValueChanged
    29. Invalidate()
    30. End Sub
    31. End Class
    Durch das End Using wird img doch wieder Disposed, daher dürfte das doch kein Problem sein, oder? Trotzdem wird offenbar alles im RAM behalten, jedenfalls bekomme ich bei einem zu großen Bildausschnitt immer nen OutOfMemory.
    @BjöNi:: Gib Deinen Dateien vernünftige Namen - Namen mit den kommunizierenden x- und y-Positionen,
    wisse, welche Positionen und Namen unterstützt sind,
    generiere Dir aus der Position den Namen der zu ladenden Datei und lade sie.
    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 Deinen Dateien vernünftige Namen - Namen mit den kommunizierenden x- und y-Positionen,
    Habe ich doch?

    RodFromGermany schrieb:

    generiere Dir aus der Position den Namen der zu ladenden Datei und lade sie.
    Es sind, wenn weggezoomt wurde, immer viele Dateien zu laden? Aber sonst tue ich das doch bereits.

    RodFromGermany schrieb:

    wisse, welche Positionen und Namen unterstützt sind,
    Ich wüsste nicht, was mir das bringt. Ein paar unnötige File.Exist-Abfragen fallen imo nicht ins Gewicht.

    BjöNi schrieb:

    Habe ich doch?
    OK.
    Da stehen iwelche kombinierten Integer-String-Operationen.
    Rechnest Du den Datei-Namen zwei Mal aus? Einmal sollte reichen.
    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:

    Rechnest Du den Datei-Namen zwei Mal aus? Einmal sollte reichen.
    Ja, das tue ich. War C&P auf die schnelle, und mir ist auch klar, dass ich das reduzieren kann. Werde ich auch noch tun. Aber das ist doch nichts, was für die OutOfMemoryException verantwortlich ist? Ich frage mich eher, warum die Bilder mit 256px*256px im RAM bleiben, obwohl sie z.B. auf 50px*50px verkleinert wurden...

    BjöNi schrieb:

    War C&P auf die schnelle
    postest Du hier einen Offline-Forum-Code, der in wesentlichen Punkten von Deinem Code abweicht?
    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:

    postest Du hier einen Offline-Forum-Code, der in wesentlichen Punkten von Deinem Code abweicht?
    Nein. Der ist - abgesehen vom Pfad - identisch. Und ich hatte auch in meinem Code das mit dem doppelten Dateinamen ausrechnen - was ich aber geändert habe. Aber das hat doch nichts damit zu tun, dass ich nen OutOfMemory kriege?!

    nafets3646 schrieb:

    Du musst sie halt Disposen
    Wen? img wird doch durch den Using-Block automatisch disposed?
    @BjöNi: Mach Dir mal ein kleines neues Testprojekt, wo Du nur mit 8 * 8 Bildern oder so experimentierst, bis der Algorithmus stimmt. Da wirst Du die Fehler wesentlich schneller finden.
    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!
    Der Algorithmus stimmt doch... Ich kann anzeigen, verschieben, zoomen... Aber wenn ich eben weit wegzoome zeichnet er den linken Teil und wirft dann ne OutOfMemoryException, wenn das Bild eingelesen wird.
    Das ist der komplette Code! Das einzige, was anders ist, sind noch ein paar Debug.WriteLine-Anweisungen... Ich verstehe das nicht so ganz.

    BjöNi schrieb:

    Das ist der komplette Code!
    Dann poste halt noch mal den aktuellen Code.
    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!

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private startpos As Point
    3. Private d As Integer = 0
    4. Private r As Integer = 0
    5. Private Sub Form1_MouseDown(sender As Object, e As MouseEventArgs) Handles Me.MouseDown
    6. startpos = e.Location
    7. End Sub
    8. Private Sub Form1_MouseUp(sender As Object, e As MouseEventArgs) Handles Me.MouseUp
    9. d -= (e.X - startpos.X) \ CInt(zoom.Value)
    10. r -= (e.Y - startpos.Y) \ CInt(zoom.Value)
    11. Invalidate()
    12. End Sub
    13. Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
    14. If e.ClipRectangle.Location <> New Point(0, 0) Then
    15. Invalidate()
    16. Return
    17. End If
    18. For x As Integer = 0 To e.ClipRectangle.Width \ CInt(zoom.Value)
    19. For y As Integer = 0 To e.ClipRectangle.Height \ CInt(zoom.Value)
    20. Dim fn As String = "...Ordner..." & (x + d).ToString & "-" & (y + r).ToString & ".png"
    21. If IO.File.Exists(fn) Then
    22. Using img As Image = Image.FromFile(fn)
    23. e.Graphics.DrawImage(img, New Rectangle(x * CInt(zoom.Value), y * CInt(zoom.Value), CInt(zoom.Value), CInt(zoom.Value)))
    24. End Using
    25. End If
    26. Next
    27. Next
    28. End Sub
    29. Private Sub zoom_ValueChanged(sender As Object, e As EventArgs) Handles zoom.ValueChanged
    30. Invalidate()
    31. End Sub
    32. End Class
    Mach den Test mit genau einem Bild 0-0.png.
    Wieso wird denn die Bildgröße nicht verwendet?
    Und mach einen solchen Test:

    VB.NET-Quellcode

    1. If e.ClipRectangle.Width = 0 Or e.ClipRectangle.Height = 0 Then
    2. 'Invalidate()
    3. Return
    4. End If
    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:

    Wieso wird denn die Bildgröße nicht verwendet?
    Ich verstehe nicht, was du meinst. Alles funktioniert wie erwartet.

    RodFromGermany schrieb:

    Und mach einen solchen Test:
    Was möchtest du damit erzielen? Du überprüfst, ob das zu zeichnende Rechteck auf einer Seite 0 px breit ist. Das kann doch aber gar nicht sein, weil dann würde das Paint-Event ja gar nicht aufgerufen.