Rubrik: Grafik und Font · Bilder & Icons | VB-Versionen: VB5, VB6 | 25.04.05 |
Inhalt einer PictureBox als JPG speichern Die Picturebox erlaubt nur das speichern von BMP Dateien. Mit dieser GDI+ Prozedur wird dem Abhilfe geschaffen. | ||
Autor: Mike B. Wehrli | Bewertung: | Views: 30.845 |
ohne Homepage | System: WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
Die PictureBox ist eine praktische Sache. Bild laden, darauf malen und dann wieder speichern. NUR leider erlaubt diese ganz im Gegensatz zum Laden, wo sie GIF, JPG usw akzeptiert, beim Speichern nur das BMP-Format. Dieses ist z.B. im Bereich von Web & Co. absolut unbrauchbar. Es gibt im Web einige Ansätze mit Konvertierungstools. Einfacher und direkt geht es aber dank GDI+...
Am besten man legt den folgenden Code in eine neue Modul-Datei:
Option Explicit ' Zunächst die nötigen Deklarationen Private Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(0 To 7) As Byte End Type Private Type GdiplusStartupInput GdiplusVersion As Long DebugEventCallback As Long SuppressBackgroundThread As Long SuppressExternalCodecs As Long End Type Private Type EncoderParameter GUID As GUID NumberOfValues As Long type As Long Value As Long End Type Private Type EncoderParameters Count As Long Parameter As EncoderParameter End Type Private Declare Function GdiplusStartup Lib "GDIPlus" ( _ token As Long, _ inputbuf As GdiplusStartupInput, _ Optional ByVal outputbuf As Long = 0) As Long Private Declare Function GdiplusShutdown Lib "GDIPlus" ( _ ByVal token As Long) As Long Private Declare Function GdipCreateBitmapFromHBITMAP Lib "GDIPlus" ( _ ByVal hbm As Long, _ ByVal hpal As Long, _ Bitmap As Long) As Long Private Declare Function GdipDisposeImage Lib "GDIPlus" ( _ ByVal Image As Long) As Long Private Declare Function GdipSaveImageToFile Lib "GDIPlus" ( _ ByVal Image As Long, _ ByVal Filename As Long, _ clsidEncoder As GUID, _ encoderParams As Any) As Long Private Declare Function CLSIDFromString Lib "ole32" ( _ ByVal str As Long, _ id As GUID) As Long
Nun zur eigentlichen Routine:
Public Sub Save_JPG( _ ByVal pict As StdPicture, _ ByVal filename As String, _ Optional ByVal quality As Byte = 200) Dim tSI As GdiplusStartupInput Dim lRes As Long Dim lGDIP As Long Dim lBitmap As Long ' GDI+ initalisieren tSI.GdiplusVersion = 1 lRes = GdiplusStartup(lGDIP, tSI) If lRes = 0 Then ' Erstelle GDI+ Bitmap aus dem Image Handler lRes = GdipCreateBitmapFromHBITMAP(pict.Handle, 0, lBitmap) If lRes = 0 Then Dim tJpgEncoder As GUID Dim tParams As EncoderParameters ' Initialiseren des Encoders CLSIDFromString StrPtr("{557CF401-1A04-11D3-9A73-0000F81EF32E}"), tJpgEncoder ' Nun die Parametrierung... tParams.Count = 1 With tParams.Parameter ' Quality ' Quality GUID festlegen CLSIDFromString StrPtr("{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"), .GUID .NumberOfValues = 1 .type = 4 .Value = VarPtr(Quality) End With ' Speichern des Bildes lRes = GdipSaveImageToFile(lBitmap, StrPtr(Filename), tJpgEncoder, tParams) ' Zerstören des Bildes GdipDisposeImage lBitmap End If ' GDI+ deinitalisieren GdiplusShutdown lGDIP End If If lRes Then Err.Raise 5, , "Speicherung des Bildes fehlgeschlagen. GDI+ Error:" & lRes End If End Sub
Um nun den Inhalt einer PictureBox zu speichern, benutzt man einfach folgenden Code:
Dim IMG_Container As New StdPicture ' .Picture, wenn nur das 'Hintergrundbild' gespeichert werden soll Set IMG_Container = PictureBox1.Image Save_JPG IMG_Container, "C:\TEST.JPG", 100
Will man Informationen, welche mit den Methoden PSet, Line usw in die PictureBox gezeichnet wurden, mitspeichern, benutzt man den Property .Image bei der Variablenzuweisung in das StdPicture Objekt. Hier ist es wichtig darauf zu achten, dass die AutoRedraw-Eigenschaft der PictureBox auf True gesetzt ist. Will man nur das zuvor geladene Bild ohne das eigene Kunstwerk sichern, ist das Property .Picture zu verwenden.
Der Parameter "quality" erlaubt die Einstellung der vom JPEG bekannten Qulitäts-Kompressionsrate:
0 = maximale Kompression, geringe Bildqualität
100 = geringste Kompression, relativ größte Qualität
Sollte beim Speichern etwas schief gelaufen sein, erfährt man dies über den Errorcode...
Allgemeines zum JPG-Format:
Es wird immer gesagt, bei der maximalen Einstellung, fände keine Kompression statt. Das ist ein weit verbreiteter Irrtum. Es gibt zudem keine verlustfreie JPG-Kompression. Qualitativ hochwertige Bitmaps verlieren auch bei der Einstellung 100 einige Details und unterliegen einem (freilich nahezu unsichtbaren) Qualitätsverlust. Für die Zwischenspeicherung von Bildern, die noch nachbearbeitet werden sollen, ist das JPG-Format deshalb wenig geeignet.
Einige weitere nützliche Hinweise zur JPG-Kompression:
- Als optimale Einstellung mit relativ hoher Kompression bei möglichst geringem Qualitätsverlust werden Werte im Bereich 90 bis 95 angegeben. Kompressionsfaktoren im Intervall 96-100 komprimieren vergleichsweise wenig, bei trotzdem deutlichen Qualitätsverlusten.
- Für die Verwendung von Bildern im WEB, bei denen gewisse Qualitätseinschränkungen hingenommen werden können, empfiehlt die einschlägige Literatur Qualitätsstufen im Bereich 50 bis 70.
- Für Graphiken und Diagramme, die oft nur eine geringe Farbenanzahl aufweisen, ist die JPG-Komprimierung aufgrund ihrer "Blockstruktur" wenig geeignet. Hier wird als bessere Alternative das GIF-Format favorisiert.
Weiter ist bei der Distribution der eigenen Software darauf zu achten, dass GDI+ erst ab W2k per Standard unterstützt wird. Ältere Betriebssysteme müssen nachgerüstet werden!