| |
VB.NET - FortgeschritteneImage/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 | |
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. | |
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 | |
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 ! | |
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 | |
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. | |
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 | |
| 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 |
|
|
Neu! sevDTA 3.0 Pro
SEPA mit Kontonummernprüfung
Erstellen von SEPA-Dateien mit integriertem BIC-Verzeichnis und Konto- nummern-Prüfverfahren, so dass ungültige Bankdaten bereits im Vorfeld ermittelt werden können. Weitere InfosTipp des Monats TOP Entwickler-Paket
TOP-Preis!!
Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR...
Jetzt nur 599,00 EURWeitere Infos
|