Hier zunächst eine serialisierbare Klasse,
die eine Liste von Bildern in JPEG-komprimierter Form im
Speicher ablegt. Die Add-Methode akzeptiert eine Size-Angabe.
Imports System.Collections.Generic
Imports System.Drawing
Imports System.IO
Imports System.Math
<System.Serializable()> _
Public Class PicSeries
Implements System.IDisposable
'Members
Friend piclist As List(Of MemoryStream)
Friend picpath As List(Of String)
Friend picquality As Integer
'JPEG komprimieren
<System.NonSerialized()> _
Dim EncoderInfo As Imaging.ImageCodecInfo
<System.NonSerialized()> _
Dim EncoderParameters As New Imaging.EncoderParameters
Friend Sub InitEncoder()
EncoderInfo = GetEncoderInfo("JPEG")
EncoderParameters = New Imaging.EncoderParameters(1)
EncoderParameters.Param(0) = New _
Imaging.EncoderParameter(Imaging.Encoder.Quality, CType(picquality, _
System.Int32))
End Sub
Public Sub New(Optional ByVal quality As Integer = 85)
picquality = Min(Max(50, quality), 95)
piclist = New List(Of MemoryStream)
picpath = New List(Of String)
InitEncoder()
End Sub
''' <summary>Anhängen eines Bildes</summary>
''' <param name="file">Pfad der Bilddatei</param>
''' <param name="Picsize">Größe des Bildes im Speicher</param>
''' <returns>Listen-Index des Bildes (oder -1)</returns>
Friend Function Add(ByVal file As String, ByVal Picsize As Size) As Integer
Dim pt, pl, pw, ph As Integer
Dim ms As New MemoryStream
Try
Using bmp As New Bitmap(file), _
ibmp As New Bitmap(Picsize.Width, Picsize.Height, _
Imaging.PixelFormat.Format24bppRgb), _
gr As Graphics = Graphics.FromImage(ibmp)
'Bildgröße in Fläche einpassen und Bild zentrieren
pt = 0 : pl = 0 : pw = bmp.Width : ph = bmp.Height
If pw > Picsize.Width Then
pw = Picsize.Width : ph = CInt(bmp.Height * pw / bmp.Width)
pt = (Picsize.Height - ph) \ 2
End If
If ph > Picsize.Height Then
ph = Picsize.Height : pw = CInt(bmp.Width * ph / bmp.Height)
pl = (Picsize.Width - pw) \ 2 : pt = 0
End If
'Bild in neuer Größe zeichnen
Dim srcrect As New Rectangle(0, 0, bmp.Width, bmp.Height)
Dim destrect As New Rectangle(pl, pt, pw, ph)
gr.Clear(Color.White)
gr.DrawImage(bmp, destrect, srcrect, GraphicsUnit.Pixel)
'Bilddaten komprimieren
ibmp.Save(ms, EncoderInfo, EncoderParameters)
'komprimierte Bilddaten an Liste anhängen
piclist.Add(ms) : picpath.Add(file)
End Using
Return piclist.Count - 1
Catch ex As System.Exception
ms.Close() 'Speicher freigeben
Return -1
End Try
End Function
''' <summary>Bildstream aus der Liste entfernen</summary>
''' <param name="index">Index des Bildes</param>
Friend Sub RemoveAt(ByVal index As Integer)
piclist(index).Close()
piclist.RemoveAt(index) : picpath.RemoveAt(index)
End Sub
''' <summary>Hilfsfunktion ermittelt den GDI+-Encoder zu einem
' Bildformat-Descriptor</summary>
Private Function GetEncoderInfo( _
ByVal FormatDescriptor As String) As Imaging.ImageCodecInfo
Dim i As Integer = 0
Dim encoders() As Imaging.ImageCodecInfo = _
Imaging.ImageCodecInfo.GetImageEncoders()
FormatDescriptor = FormatDescriptor.ToUpper.Trim
While i < encoders.Length
If encoders(i).FormatDescription.ToUpper = FormatDescriptor Then
Return encoders(i)
End If
i += 1
End While
Return Nothing
End Function
Private disposedValue As Boolean
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
While piclist.Count > 0
RemoveAt(0)
End While
End If
End If
Me.disposedValue = True
End Sub
Public Sub Dispose() Implements System.IDisposable.Dispose
Dispose(True)
System.GC.SuppressFinalize(Me)
End Sub
End Class |