vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
TOP-Angebot: 17 bzw. 24 Entwickler-Vollversionen zum unschlagbaren Preis!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Fortgeschrittene
Image/Bitmap verändert sich ohne Änderungen durch den Code ???  
Autor: Jojo
Datum: 25.04.18 08:08

Hallo,

ich habe eine relativ komplexe funktion, die mir Bilder umwandelt. Dazu werden große Bilder geladen und in verschidene andere Formate umgewandelt und abgespeichert. Im Rahmen einer Optimierung wurde der Code geändert und ich lese die Bilder jetzt aus MemoryStream statt dem umweg über die lokale Platte. Soweit so gut. Komischerweise verändert sich das Bild - ohne dass die Variable im Code verwendet wird.

Hier mal der Code:
Es wird ein Bild von einer URL geladen in StreamBild. Dann werden zwei funktionen aufgerufen, die jeweils ein Bild 120 und 600 erstellen sollen.

Dim StreamBild As Image = Nothing
Dim wc As New Net.WebClient()
Using stream As New IO.MemoryStream(wc.DownloadData(DR("SourceUrl").ToString))
   StreamBild = Image.FromStream(stream)
End Using
 
If StreamBild IsNot Nothing Then
      Using myimage As Bitmap = StreamBild
      'Bild 120
      imageConvert(myimage, 120, 120, Imaging.ImageFormat.Jpeg, Dateiname, _
        False, False, 120, 120)
      'Bild600
      ImageConvert(myimage, 300, 300, Imaging.ImageFormat.Jpeg, Dateiname600, _
        False, False, 300, 300)
   End Using
End If
Das Komische ist, dass die erste ImageConvert das Bild in 120x120 erstellt. Beim Aufruf des Bild600 ist myimage nothing

Public Sub imageConvert(ByVal ConvertBild As Bitmap, ByVal nWidth As Integer, _
  ByVal nHeight As Integer, ByVal nFormat As ImageFormat, ByVal sNewFile As _
  String, Optional ByVal CropImage As Boolean = False, Optional ByVal _
  RotateImage As Boolean = True, Optional ByVal fixWidth As Integer = 0, _
  Optional ByVal fixHeight As Integer = 0)
 
   ' Neues Bild-Objekt in der neu berechneten Breite und Höhe erstellen
   Using neuesBild As Bitmap = ConvertBild
 
      '---- Bild auf die Festgelegte Höhe und Breite bringen ----
      If System.IO.File.Exists(sNewFile) Then System.IO.File.Delete(sNewFile)
 
      Dim NewPosY As Integer = 0, NewPosX As Integer = 0
      If fixHeight > neuesBild.Height Then NewPosY = CInt((fixHeight - _
        neuesBild.Height) / 2)
      If fixWidth > neuesBild.Width Then NewPosX = CInt((fixWidth - _
      neuesBild.Width) / 2)
      Using fixBmp As Bitmap = New Bitmap(fixWidth, fixHeight, _
      PixelFormat.Format32bppArgb)
         Using g As Drawing.Graphics = Graphics.FromImage(fixBmp)
            g.Clear(Color.White)
            g.SmoothingMode = SmoothingMode.HighQuality
            g.CompositingQuality = CompositingQuality.HighQuality
            g.InterpolationMode = InterpolationMode.High
            g.DrawImage(neuesBild, New RectangleF(NewPosX, NewPosY, _
              neuesBild.Width, neuesBild.Height), New RectangleF(0, 0, _
              neuesBild.Width, neuesBild.Height), GraphicsUnit.Pixel)
            fixBmp.Save(sNewFile, nFormat)
         End Using
      End Using
   End Using
End Sub
Die Funktion imageConvert (war eine Funtion, habe ich jetzt in eine Sub umgewandelt zum test) verändert die Ursprungsvariable nicht. Dennoch ist nach dem Ausführen der Sub die Ursprüngliche Variable nothing

Wer kann mir erklären, was hier passiert?

Joachim

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Image/Bitmap verändert sich ohne Änderungen durch den Code ??? 
Autor: Manfred X
Datum: 25.04.18 08:59

Hallo!

Du weist in einem USING-Block bestehende Referenzen
auf die per Using verwalteten Variablen zu.
Beim Erreichen von "End Using" wird für die
entsprechenden Objekte DISPOSE ausgeführt.
Verzichte auf USING.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Image/Bitmap verändert sich ohne Änderungen durch den Code ??? 
Autor: Jojo
Datum: 25.04.18 09:35

Die Verwendung von Using habe ich erst verwendet, nachdem ich es ohne versucht habe.

Das Result diese Code ist exakt das gleiche:

                    If StreamBild IsNot Nothing Then
                        Dim myimage As Bitmap = StreamBild
                        'Bild 120
                        imageConvert(myimage, 120, 120, _
                          Imaging.ImageFormat.Jpeg, Dateiname, False, False, _
                          120, 120)
                        'Bild600
                        imageConvert(myimage, 300, 300, _
                          Imaging.ImageFormat.Jpeg, Dateiname.Replace( _
                          "images120", "images600"), False, False, 300, 300)
 
                        myimage.Dispose()
                    End If
auch beim Image600 ist myimage nothing

    Public Sub imageConvert(ByVal ConvertBild As Bitmap, ByVal nWidth As _
      Integer, ByVal nHeight As Integer, ByVal nFormat As ImageFormat, ByVal _
      sNewFile As String, Optional ByVal CropImage As Boolean = False, Optional _
      ByVal RotateImage As Boolean = True, Optional ByVal fixWidth As Integer = _
      0, Optional ByVal fixHeight As Integer = 0)
 
        ' Neues Bild-Objekt in der neu berechneten Breite und Höhe erstellen
        Dim neuesBild As Bitmap = ConvertBild
 
        '---- Bild auf die Festgelegte Höhe und Breite bringen ----
        If System.IO.File.Exists(sNewFile) Then System.IO.File.Delete(sNewFile)
 
            Dim NewPosY As Integer = 0, NewPosX As Integer = 0
            If fixHeight > neuesBild.Height Then NewPosY = CInt((fixHeight - _
              neuesBild.Height) / 2)
            If fixWidth > neuesBild.Width Then NewPosX = CInt((fixWidth - _
            neuesBild.Width) / 2)
            Dim fixBmp As Bitmap = New Bitmap(fixWidth, fixHeight, _
            PixelFormat.Format32bppArgb)
 
            Dim g As Drawing.Graphics = Graphics.FromImage(fixBmp)
                g.Clear(Color.White)
                    g.SmoothingMode = SmoothingMode.HighQuality
                    g.CompositingQuality = CompositingQuality.HighQuality
                    g.InterpolationMode = InterpolationMode.High
                    g.DrawImage(neuesBild, New RectangleF(NewPosX, NewPosY, _
                      neuesBild.Width, neuesBild.Height), New RectangleF(0, 0, _
                      neuesBild.Width, neuesBild.Height), GraphicsUnit.Pixel)
                    fixBmp.Save(sNewFile, nFormat)
                g.Dispose()
 
            fixBmp.Dispose()
        neuesBild.Dispose()
 
    End Sub

Joachim

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Image/Bitmap verändert sich ohne Änderungen durch den Code ??? 
Autor: Jojo
Datum: 25.04.18 09:50

Interesant ist folgendes:

Dim myimage As Bitmap = StreamBild
                        'Bild 120
                        test(myimage)
                        'Bild600
                        test(myimage)
Rufe ich damit eine sehr einfache Sub auf, wo die neue Variable am Ende richtig zerstört wird, dann ist immer die Ursprüngliche Variable (myImage) auch gelöscht:

    Sub test(Bild As Bitmap)
        'nichts machen
        Dim neuesBild As Bitmap = Bild
        neuesBild.Dispose()
    End Sub
Ohne das Dispose() - bleibt die ursprüngliche Variable erhalten

Das gleiche bei passiert bei Using. Auch hier ist Myimage hinterher nothing
Sub test(Bild As Bitmap)
        Using neuesBild As Bitmap = Bild
            'nichts machen
        End Using
    End Sub
Ich bin da sehr dahinter her, dass die Variablen alle wieder zerstört werden. Ich hatte in der Vergangenheit das Problem, dass der Speicherbedarf ins endlose steigt.

Wer kann mir erklären, warum das Auswirkungen auf den Wert hat, den ich ursprünglich übergeben habe?

Joachim

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Image/Bitmap verändert sich ohne Änderungen durch den Code ??? 
Autor: Manfred X
Datum: 25.04.18 10:08

Noch einmal:
Wenn Du Dispose rufst, werden die Resourcen des zugrundeliegenden Objekts
(Bitmap) freigegeben.

Dieser Code erzeugt kein neue Bild:
Dim neuesBild As Bitmap = Bild

Laß das Dispose weg !
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Image/Bitmap verändert sich ohne Änderungen durch den Code ??? 
Autor: Jojo
Datum: 25.04.18 10:22

Hallo Manfred,

das Du recht hast ist mir klar. Im Test funktioniert es ohne das Dispose() bzw ohne using.

Verstanden habe ich es nicht. Wieso die resourcen des zugrundeliegenen objects?

Wenn ich
dim neuesBild as bitmap = altesBild
'tu irgendwas - z.b drehen um 90°
'Save neues Bild
Dann habe ich aus meiner Sicht zweit unterschiedliche Objekte. Ein altes Bild und ein neues Bild.
Ich verstehe nicht, warum das neueBild.dispose() sich auf das alteBild auswirkt.

Kannst Du es erklären?

Joachim

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Image/Bitmap verändert sich ohne Änderungen durch den Code ??? 
Autor: Manfred X
Datum: 25.04.18 11:09

Das ist die zentrale Grundlage des objektorientierten Programmierens.

Es gibt Objekte (=Klassen-Instanzen) im Hauptspeicher, die durch
das Schlüsselwort "New" erstellt oder z.B. durch "Copy"- bzw. "Clone"-Methoden
einer Klasse als Doubletten zu einem bestehenden Objekt erzeugt worden sind.

Verwendet werden solche Objekte im Code durch Referenzvariablen.
Ich nenne sie auch Zugriffvariablen. Sie enthalten einen
"Zeiger" auf ein Objekt im Speicher - oder sie enthalten
keinen Zeiger (= Zeiger auf Nothing).

Dim neuesBild as bitmap = altesBild
"Bitmap" ist eine Klasse. Von ihr können Objekte erstellt werden.
Die Referenzvariable "AltesBild" zeigt auf ein solches Bitmap-Objekt.
Die Zuweisung auf "NeuesBild" gibt nur die Referenz auf dieses Objekt
weiter. Beide Variablen zeigen auf das identische Speicherobjekt.
Um ein neues Bildobjekt zu erstellen, gibt es bei dieser Klasse
die Clone-Methode.

Lies mal ein Grundlagenbuch!

Dim bmp as New Bitmap(...)
Was geschieht?
1. Es wird eine neue Instanz der Klasse Bitmap im Speicher erstellt (New)
2. Nicht-verwaltete Bitmap-Ressourcen werden diesem Objekt bereit gestellt.
3. Ein Konstruktor dieser Klasse wird ausgeführt (z.B. Bilddatei laden)
4. Es wird eine Referenzvariable "bmp" erstellt, die auf ein Bitmap-Objekt zeigen kann.
5. Die Referenzvariable wird auf das neue Objekt "referenziert" (= Zeigerzuweisung)

Beitrag wurde zuletzt am 25.04.18 um 11:16:51 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Image/Bitmap verändert sich ohne Änderungen durch den Code ??? 
Autor: Jojo
Datum: 25.04.18 12:05

Hallo Manfred, danke für die gut verständliche Erklärung.

Joachim

Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel