Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0664: Vorschaubild mit GDI+ erstellen und anzeigen

 von 

Beschreibung 

Dieser Tipp zeigt wie man unter Verwendung von GDI+ ein Vorschaubild einer Grafik erstellen und anzeigen kann. Hierbei ist es möglich anzugeben wieviel Prozent der Originalgröße die zu erstellende Grafik haben soll. Hierdurch wird auch eine Vergrößerung, jedoch ohne vernünftige Interpolation, ermöglicht.

Schwierigkeitsgrad:

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

GdipCreateHBITMAPFromBitmap, GdipDisposeImage, GdipGetImageDimension, GdipGetImageThumbnail, GdipLoadImageFromFile, GdiplusShutdown, GdiplusStartup, OleCreatePictureIndirect

Download:

Download des Beispielprojektes [4,62 KB]

'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'----- Anfang Projektdatei GDIPlusThumbnailFromFile.vbp -----
' Die Komponente 'Microsoft Common Dialog Control 6.0 (SP3) (comdlg32.ocx)' wird benötigt.

'--- Anfang Formular "frmGDIPlusThumbnailFromFile" alias frmGDIPlusThumbnailFromFile.frm  ---
' Steuerelement: Horizontale Scrollbar "HScroll1"
' Steuerelement: Bildfeld-Steuerelement "Picture1"
' Steuerelement: Standarddialog-Steuerelement "CommonDialog1"
' Steuerelement: Schaltfläche "cmdLoadPicture"
' Steuerelement: Beschriftungsfeld "Label1"

Option Explicit

' ----==== GDIPlus Const ====----
Private Const GdiPlusVersion As Long = 1

' ----==== Sonstige Types ====----
Private Type PICTDESC
    cbSizeOfStruct As Long
    picType As Long
    hgdiObj As Long
    hPalOrXYExt As Long
End Type

Private Type IID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(0 To 7)  As Byte
End Type

' ----==== GDIPlus Types ====----
Private Type GDIPlusStartupInput
    GdiPlusVersion As Long
    DebugEventCallback As Long
    SuppressBackgroundThread As Long
    SuppressExternalCodecs As Long
End Type

' ----==== GDIPlus Enums ====----
Private Enum Status 'GDI+ Status
    OK = 0
    GenericError = 1
    InvalidParameter = 2
    OutOfMemory = 3
    ObjectBusy = 4
    InsufficientBuffer = 5
    NotImplemented = 6
    Win32Error = 7
    WrongState = 8
    Aborted = 9
    FileNotFound = 10
    ValueOverflow = 11
    AccessDenied = 12
    UnknownImageFormat = 13
    FontFamilyNotFound = 14
    FontStyleNotFound = 15
    NotTrueTypeFont = 16
    UnsupportedGdiplusVersion = 17
    GdiplusNotInitialized = 18
    PropertyNotFound = 19
    PropertyNotSupported = 20
    ProfileNotFound = 21
End Enum

' ----==== GDI+ API Declarationen ====----
Private Declare Function GdiplusStartup Lib "gdiplus" _
    (ByRef token As Long, ByRef lpInput As GDIPlusStartupInput, _
    Optional ByRef lpOutput As Any) As Status

Private Declare Function GdiplusShutdown Lib "gdiplus" _
    (ByVal token As Long) As Status

Private Declare Function GdipLoadImageFromFile Lib "gdiplus" _
    (ByVal FileName As Long, ByRef image As Long) As Status

Private Declare Function GdipGetImageThumbnail Lib "gdiplus" _
    (ByVal image As Long, ByVal thumbWidth As Long, _
    ByVal thumbHeight As Long, ByRef thumbImage As Long, _
    ByVal callback As Long, ByVal callbackData As Long) _
    As Status

Private Declare Function GdipGetImageDimension Lib "gdiplus" _
    (ByVal image As Long, ByRef Width As Single, _
    ByRef Height As Single) As Status

Private Declare Function GdipCreateHBITMAPFromBitmap Lib "gdiplus" _
    (ByVal Bitmap As Long, ByRef hbmReturn As Long, _
    ByVal background As Long) As Status

Private Declare Function GdipDisposeImage Lib "gdiplus" _
    (ByVal image As Long) As Status

' ----==== OLE API Declarations ====----
Private Declare Sub OleCreatePictureIndirect Lib "oleaut32.dll" _
    (lpPictDesc As PICTDESC, riid As IID, ByVal fOwn As Boolean, _
    lplpvObj As Object)

' ----==== Variablen ====----
Private GdipToken As Long
Private GdipInitialized As Boolean

'------------------------------------------------------
' Funktion     : StartUpGDIPlus
' Beschreibung : Initialisiert GDI+ Instanz
' Übergabewert : GDI+ Version
' Rückgabewert : GDI+ Status
'------------------------------------------------------
Private Function StartUpGDIPlus(ByVal GdipVersion As Long) As Status
    ' Initialisieren der GDI+ Instanz
    Dim GdipStartupInput As GDIPlusStartupInput
    GdipStartupInput.GdiPlusVersion = GdipVersion
    StartUpGDIPlus = GdiplusStartup(GdipToken, GdipStartupInput, ByVal 0)
End Function

'------------------------------------------------------
' Funktion     : ShutdownGDIPlus
' Beschreibung : Beendet die GDI+ Instanz
' Rückgabewert : GDI+ Status
'------------------------------------------------------
Private Function ShutdownGDIPlus() As Status
    ' Beendet GDI+ Instanz
    ShutdownGDIPlus = GdiplusShutdown(GdipToken)
End Function

'------------------------------------------------------
' Funktion     : Execute
' Beschreibung : Gibt im Fehlerfall die entsprechende GDI+ Fehlermeldung aus
' Übergabewert : GDI+ Status
' Rückgabewert : GDI+ Status
'------------------------------------------------------
Private Function Execute(ByVal lReturn As Status) As Status
    Dim lCurErr As Status
    If lReturn = Status.OK Then
        lCurErr = Status.OK
    Else
        lCurErr = lReturn
        Call MsgBox(GdiErrorString(lReturn) & " GDI+ Error:" & lReturn, _
                     vbOKOnly, "GDI Error")
    End If
    Execute = lCurErr
End Function

'------------------------------------------------------
' Funktion     : GdiErrorString
' Beschreibung : Umwandlung der GDI+ Statuscodes in Stringcodes
' Übergabewert : GDI+ Status
' Rückgabewert : Fehlercode als String
'------------------------------------------------------
Private Function GdiErrorString(ByVal lError As Status) As String
    Dim s As String
    
    Select Case lError
    Case GenericError:              s = "Generic Error."
    Case InvalidParameter:          s = "Invalid Parameter."
    Case OutOfMemory:               s = "Out Of Memory."
    Case ObjectBusy:                s = "Object Busy."
    Case InsufficientBuffer:        s = "Insufficient Buffer."
    Case NotImplemented:            s = "Not Implemented."
    Case Win32Error:                s = "Win32 Error."
    Case WrongState:                s = "Wrong State."
    Case Aborted:                   s = "Aborted."
    Case FileNotFound:              s = "File Not Found."
    Case ValueOverflow:             s = "Value Overflow."
    Case AccessDenied:              s = "Access Denied."
    Case UnknownImageFormat:        s = "Unknown Image Format."
    Case FontFamilyNotFound:        s = "FontFamily Not Found."
    Case FontStyleNotFound:         s = "FontStyle Not Found."
    Case NotTrueTypeFont:           s = "Not TrueType Font."
    Case UnsupportedGdiplusVersion: s = "Unsupported Gdiplus Version."
    Case GdiplusNotInitialized:     s = "Gdiplus Not Initialized."
    Case PropertyNotFound:          s = "Property Not Found."
    Case PropertyNotSupported:      s = "Property Not Supported."
    Case Else:                      s = "Unknown GDI+ Error."
    End Select
    
    GdiErrorString = s
End Function

'------------------------------------------------------
' Funktion     : CreateThumbnailFromFile
' Beschreibung : Lädt ein Bilddatei per GDI+
' Übergabewert : FileName = Pfad\Dateiname der Bilddatei
'                Percent = Größe in Prozent (100% = 1:1)
' Rückgabewert : StdPicture Objekt
'------------------------------------------------------
Private Function CreateThumbnailFromFile(ByVal FileName As String, _
ByVal Percent As Long) As StdPicture
    
    Dim retStatus As Status
    Dim lBitmap As Long
    Dim lThumb As Long
    Dim hBitmap As Long
    Dim ImageWidth As Single
    Dim ImageHeight As Single
    Dim IW As Long
    Dim IH As Long
    
    ' Öffnet die Bilddatei in lBitmap
    retStatus = Execute(GdipLoadImageFromFile(StrPtr(FileName), _
        lBitmap))
    
    If retStatus = OK Then
        
        ' Ermitteln der ImageDimensionen
        Call Execute(GdipGetImageDimension(lBitmap, ImageWidth, _
            ImageHeight))
            
        IW = (ImageWidth * Percent) \ 100
        IH = (ImageHeight * Percent) \ 100
        
        ' Thumbnail erzeugen
        retStatus = Execute(GdipGetImageThumbnail(lBitmap, IW, IH, _
            lThumb, 0, 0))
        
        If retStatus = Status.OK Then
            
            ' Erzeugen der GDI Bitmap von der Thumbnail Bitmap
            retStatus = Execute(GdipCreateHBITMAPFromBitmap(lThumb, _
                hBitmap, 0))
            
            If retStatus = Status.OK Then
                
                ' Erzeugen des StdPicture Objekts von hBitmap
                Set CreateThumbnailFromFile = _
                    HandleToPicture(hBitmap, vbPicTypeBitmap)
            End If
            
            ' Lösche lThumb
            Call Execute(GdipDisposeImage(lThumb))
        End If
        
        ' Lösche lBitmap
        Call Execute(GdipDisposeImage(lBitmap))
    End If
End Function

'------------------------------------------------------
' Funktion     : HandleToPicture
' Beschreibung : Umwandeln einer GDI+ Bitmap Handle in ein
'                StdPicture Objekt
' Übergabewert : hGDIHandle = GDI+ Bitmap Handle
'                ObjectType = Bitmaptyp
' Rückgabewert : StdPicture Objekt
'------------------------------------------------------
Private Function HandleToPicture(ByVal hGDIHandle As Long, _
    ByVal ObjectType As PictureTypeConstants, _
    Optional ByVal hpal As Long = 0) As StdPicture
    
    Dim tPictDesc As PICTDESC
    Dim IID_IPicture As IID
    Dim oPicture As IPicture
    
    ' Initialisiert die PICTDESC Structur
    With tPictDesc
        .cbSizeOfStruct = Len(tPictDesc)
        .picType = ObjectType
        .hgdiObj = hGDIHandle
        .hPalOrXYExt = hpal
    End With
    
    ' Initialisiert das IPicture Interface ID
    With IID_IPicture
        .Data1 = &H7BF80981
        .Data2 = &HBF32
        .Data3 = &H101A
        .Data4(0) = &H8B
        .Data4(1) = &HBB
        .Data4(3) = &HAA
        .Data4(5) = &H30
        .Data4(6) = &HC
        .Data4(7) = &HAB
    End With
    
    ' Erzeugen des Objekts
    OleCreatePictureIndirect tPictDesc, IID_IPicture, True, oPicture
    
    ' Rückgabe des Pictureobjekts
    Set HandleToPicture = oPicture
    
End Function

Private Sub cmdLoadPicture_Click()
    On Error Goto errorhandler
    
    If GdipInitialized = True Then
        
        With CommonDialog1
           .Filter = "Images Files " & _
                     "(*.bmp;*.gif;*.jpg;*.png;*.tif)" & _
                     "|*.bmp;*.gif;*.jpg;*.png;*.tif"
           .CancelError = True
           .ShowOpen
        End With
        
        Picture1.Picture = CreateThumbnailFromFile _
            (CommonDialog1.FileName, HScroll1.Value)
    
    End If
    
    Exit Sub
errorhandler:
End Sub

Private Sub Form_Load()
    Dim retStatus As Status
    GdipInitialized = False
    
    retStatus = Execute(StartUpGDIPlus(GdiPlusVersion))
    If retStatus = OK Then
        GdipInitialized = True
    Else
        MsgBox "GDI+ not inizialized.", vbOKOnly, "GDI Error"
    End If
    
    With HScroll1
        .Max = 200
        .Min = 1
        .Value = 50
    End With
    
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Dim retStatus As Status

    If GdipInitialized = True Then
        retStatus = Execute(ShutdownGDIPlus)
    End If
End Sub

Private Sub HScroll1_Change()
    Label1.Caption = "Thumbnail in " & HScroll1.Value & "% der Originalgröße"
End Sub

Private Sub HScroll1_Scroll()
    HScroll1_Change
End Sub
'--- Ende Formular "frmGDIPlusThumbnailFromFile" alias frmGDIPlusThumbnailFromFile.frm  ---
'------ Ende Projektdatei GDIPlusThumbnailFromFile.vbp ------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 24 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von Frank Schüler am 24.10.2008 um 20:07

Hi Fieber

Hier ist nicht der richtige Platz dafür um eine Lösung für dieses Problem zu erörtern. Mache doch einfach ein Posting im VB5/6 Forum auf. Dann können sich auch andere bei der Lösung beteiligen.

Kommentar von Fieber am 24.10.2008 um 13:12

Hallo Frank,
zur Zeit verändere ich das Bild immer um 2 Pixel größer und schneide es anschließend aus. Funktioniert bei großen Bildern gut aber bei kleinen Bildern siet man, daß was an Bildinformationen fehlt.
Ich habe die möglichkeit eingebaut GDI+ auszuschalten und dann benutze ich StretchBlt mit SetStretchBltMode.
Ich glaube, das mit der Matrx ist mir zu kompiziert. Gibt es denn irgendwie ein Beispiel-Script dafür.
Vielen Dank und Gruß aus Berlin
Fieber

Kommentar von Frank Schüler am 24.10.2008 um 06:51

Hi Fieber

Das Problem, das beim vergrößern oder verkleinern ein Rand entsteht ist bekannt. Es handelt sich hier um einen Bug in der GDI+. Dieses Problem kann man aber mit einem etwas kompliziertem Workaround umgehen. Es gibt dazu zwei Möglichkeiten. Entwerder man implementiert eine eigene InterpolationMode-Funktion über eine 3x3 Matrix bei der die Randpixel entsprechend anders berechnet werden oder man erstellt ein Bild in entsprechender Größe + Breite des Randes und vergrößert das Bild + Breite des Randes mit dem InterpolationMode NearestNeighbor und danach noch mal um den Rand versetzt mit einem anderem InterpolationMode und schneidet danach die richtige Größe wieder aus diesem Bild aus. Alles recht kompliziert.

Alternativ, und einfacher, kannst Du Dein Bild mit StretchBlt und entsprechend gesetztem SetStretchBltMode vergrößern oder verkleinern ohne das ein Rand entsteht.

Mfg Frank

Kommentar von Fieber am 24.10.2008 um 01:04

Ich suche ein Script, um ein Bild (Bitmap) mit GDI+ (Interlaced) zu vergrößern oder zu verkleinern. Auch große Bilder (12 MPx) und getrennt nach Höhe und Breite (Stretch).
Zur Zeit arbeite ich mit den APIs:
GdipSetInterpolationMode
GdipGetImageWidth
GdipDrawImageRectRectI

Hierbei entsteht nach der Vergrößerung oder Verkleinerung allerdings am Rand (1 Pixel breit) des Bildes bei einfarbigen Hintergrung eine Farbabweichung.
Da ich mit Masken arbeite, entsteht bei der Ausblendung des Hintergrundes immer ein Rand, der nich ausgeblendet wird.
Was kann ich machen?
Gruß
Fieber

Kommentar von Joachim Siebert am 14.01.2008 um 08:26

Moin Jungs,

das Problem mit den extrem schlechten Grafiken habe ich wie folgt gelöst:

1.) Bild mit der loadpictureplus function laden
2.) Bild speichern als JPG mit 100%
3.) Dann umwandeln ....

Dabei nimmt die GDI nicht mehr das Thumb sondern das echte Bild und alles ist top ...

Ich bin mir im klaren darüber, dass das nicht optimal ist. Wer also eine bessere idee hat - Bitte posten ...

Public Sub Thumbpicture(Input_File As String, Output_File As String, Width_Max As Integer, Height_Max As Integer, Qualität As Integer, Reduce_Only As Boolean)
Dim Percent As Long
'GFSO = FileSystemObject
If GFSO.fileexists(Input_File) = True Then
Picture1.Picture = LoadPicturePlus(Input_File)
If 100 / Picture1.ScaleHeight * Height_Max > 100 / Picture1.ScaleWidth * Width_Max Then
Percent = 100 / Picture1.ScaleWidth * Width_Max
Else
Percent = 100 / Picture1.ScaleHeight * Height_Max
End If
If Reduce_Only = True And Picture1.ScaleWidth < Width_Max And Picture1.ScaleHeight < Height_Max Then
GFSO.copyfile Input_File, Output_File, True
Else
SavePictureAsJPG Picture1, "c:\temp\temp1.jpg", 100
On Error Goto errorhandler
If GdipInitialized = True Then
Picture1.Picture = CreateThumbnailFromFile("c:\temp\temp1.jpg", Percent)
SavePictureAsJPG Picture1, Output_File, Qualität
Else
End
End If
End If
Else
MsgBox ("Die Datei " & Input_File & " existiert nicht")
End If
Exit Sub
errorhandler:
End Sub

Kommentar von Frank Schüler am 01.08.2007 um 07:05

Hi D0ct0R_HaCkiE

Erstellst Du die Vorschaubilder in dieser Größe wie unter dieser WWW-Adresse zu finden ist? Dafür ist die Funktion "GdipGetImageThumbnail" nicht gedacht. Die maximale Größe für "GdipGetImageThumbnail" sollte 320x240 nicht überschreiten. Desweiteren verwendet "GdipGetImageThumbnail" bei JPEGs, wenn vorhanden, das EXIF-Vorschaubild und nicht das Originalbild, das sowieso in geringer Qualität in der JPEG vorliegt. Falls es sich ausschließlich um JPEGs handelt, dann könntest Du auch gleich diesen Tipp verwenden. http://www.activevb.de/tipps/vb6tipps/tipp0666.html um das eingebettete EXIF-Vorschaubild auszulesen.

Falls Du weitere Fragen zu diesem Thema hast, dann erstelle bitte einen Thread dazu im VB6-Forum.

MFG Frank

Kommentar von D0ct0R_HaCkiE am 30.07.2007 um 21:22

Der Tip hat mir sehr für mein Programm für eine ganze Fotoalbum-Erstellung geholfen.

Leider tauchen immerwieder seltsame Ergebnisse mit GDI+ auf.
Unter www.telcomax.info/service/ActiveVB_PICT3182.jpg ist ein Beispiel hierfür zu finden.

Normalerweise arbeitet die Routine fehlerfrei. Ich vermute, daß es daran liegt, daß die Zielgröße (keine %-Verkleinerung) nicht dem Original entspricht.
Jedoch habe ich bereits den Code entsprechend angepasst - ohne Änderung.

Kennt jemand von euch dieses Phänomen und hoffentlich auch dazu eine Lösung?

Vielen Dank schon mal im Voraus.
Doc

Kommentar von Frank Schüler am 20.11.2006 um 20:04

Hallo Jens

Nur zur Info: Die GDIPlus.dll kann man auch ohne WGA-Abfrage downloaden. http://download.microsoft.com/download/a/b/c/abc45517-97a0-4cee-a362-1957be2f24e1/gdiplus_dnld.exe

Wenn Du die Dll ersteinmal hast, darfst Du diese auch auf andere Systeme kopieren. Du musst das ganze Paket also nicht nocheinmal auf einem anderem System downloaden.

In der Redist.TXT (in gdiplus_dnld.exe enthalten) steht ganz genau, wohin Du die GDIPlus.DLL kopieren darfst.

For Windows XP use the system-supplied gdiplus.dll. Do not install a new gdiplus.dll over the system-supplied version (it will fail due to Windows File Protection).

For Windows 2000, Windows Millennium Edition, Windows NT 4.0 and Windows 98, install gdiplus.dll into the private directory of the application not into the system directory.

Und ja, es reicht, zusätzlich zu den VB-Runtime-Dateien, die GDIPlus.dll. Falls Du ein Setup von Deinem Programm erstellst musst Du darauf achten, das die GDIPlus.dll in den Programmordner kopiert wird und nicht in den Systemordner von Windows. Desweiteren braucht diese DLL nicht registriert (RegSvr32) zu werden.

MFG Frank

Kommentar von Jens am 20.11.2006 um 16:39

Hallo Frank.

Danke für Deine Bemühungen. Dein "Tipp für den Tipp" ist ja Hammermäßig. Mysteriöserweise habe ich den übersehen - vielleicht sagte mir der Name des Tipps weniger was.

Bin eben hier am experimentieren und habe soeben das gefunden, wonach ich gefunden habe. Vielen Dank :-)

Nur eine Frage, die vielleicht auch andere interessieren könnte. Ich habe ebenso darüber keine Infos gefunden.

Für das System 2000 (und abwärts) wird bekanntlich ein Plugin "WGAPluginInstall" benötigt, dass ich heute installieren wollte.

Leider kam ständig (ich probiere es meist in verschiedenen Situationen aus) - die sinnige Fehlermeldung: "Browser Installationspfad nicht gefunden". Nun habe ich einfach die Datei GdiPuls.dll in das System32 Verzeichnis kopiert und es lief.

Reicht regulär nur diese Datei aus ? Eine Datei nur zu kopieren, scheint mir irgendwie zu einfach ;-) Deshalb frage ich mal lieber nach...

Viele Grüße,
Jens

Kommentar von Frank Schüler am 20.11.2006 um 06:53

Hallo Jens

Mir ist nichts bekannt, das man GdipGetImageThumbnail dazu zwingen könnte nur das Originalimage, anstelle des JPEG-Thumbnails bei JPEGs, einzulesen. Wie der Name der Funktion ja auch schon sagt, Lese das Thumbnail der Datei. Nun ja, wenn kein Thumbnail vorhanden ist dann wird halt das Original verwendet. Beim Tipp0663 wird die JPEG ohne JPEG-Thumbnail erstellt. Daher wohl auch die bessere Qualität. Die Qualität des JPEG-Thumbnail hängt stark von der verwendeten (Kamera) Software ab. Üblicherweise werden gerade diese Thumbnails mit einer Komprimierungsqualität < 50 erstellt um so die eigentliche JPEG nicht unnötig aufzublasen. Und da hast Du selbst keinen Einfluss drauf. Hat also nichts mit GDI+ zu tun.

Was man aber machen könnte ist das JPEG-Thumbnail durch ein neues Thumbnail mit besserer Qualität zu ersetzen. Siehe dazu http://www.activevb.de/cgi-bin/upload/download.pl?id=2663

Alternativ kannst Du nur GdipLoadImageFromFile verwenden und das Bild selbst skalieren wie im Tipp0658. Da wird nur das Originalimage verwendet und nicht das Thumbnail der JPEG.

MFG Frank

Kommentar von Jens am 19.11.2006 um 11:17

Hallo. Der Tipp ist aller erste Sahne ;-)

Wie Joe am 21.02.2006 festgestellt hatte, dass bei manchen die Interpolation miserabel ist, habe ich festgestellt, dass es nur die JPG-Bilder betrifft, die das Thumbnail schon inklusive haben. Es scheint so als würde die Funktion 'GdipGetImageThumbnail' nur das Thumbnail auslesen. Ist keines vorhanden, wird der Rest danach gelesen - dann ist die Qualität auch im Originalen.

Habe nun den Tipp 663 [a href='http://www.activevb.de/tipps/vb6tipps/tipp0663.html']Grafik mittels GDI+ als JPEG speichern[/a] mit diesem Tipp vereint und das geladene Bild wieder als JPG gespeichert. Liest man das gespeicherte Bild wieder mit diesem Tipp ein, ist die Qualität super.

Laaaange Rede kurzer Sinn, kann man die Funktion GdipGetImageThumbnail nicht zwingen, das Originalbild einzulesen ?

Viele Grüße,
Jens

Kommentar von Frank Schüler am 25.10.2006 um 20:50

Hi

Schaust Du hier:
http://www.weissenburger.de/nt4/desktop.htm#20
unter "Explorer automatisch aktualisieren".

MFG Frank

Kommentar von Waibel Matthias am 25.10.2006 um 16:33

Habe ich auch gedacht, kann aber nicht so sein!!!

Ich gehe in den Explorer, klicke auf ein Bild -> Paint öffnet sich. Zeichne was rein, schließe! - >Thumbnail bei Ansicht Miniaturansicht übernimmt änderungen nicht... Starte ich das Bild mit Windows Bild-und Faxanzeige sind die Änderungen da.

Mein Programm hat damit nichts zu tun da ich es ja nicht mal starte..

mfg Matthias

Kommentar von Frank Schüler am 25.10.2006 um 16:02

Hi

Ich schätze mal, das Du irgendwo einen Fehler in Deinem Programm hast. Denn wenn die Aktualisierung der ImageBox per LoadPicture funktioniert, sollte auch die Aktualisierung der Thumbnails in Deinem Progaramm per GDI+ funktionieren. Der Explorer sollte das Thumbnail eigentlich automatisch erneuern und das hat nichts mit Paint zu tun.

MFG Frank

Kommentar von Waibel Matthias am 25.10.2006 um 15:23

Hallo

Keine Ahnung warum das so ist... Ich verwende diesen Code.
in meinem Programm wird, wenn man auf das bild klickt (imagebox) das bild im Paint geöffnet. Dann zeichne ich einen Strich ein, speichere und verlasse Paint. Nun wird in der Imagebox das Bild sofort aktualisiert (weil ganz einfach Loadpicture() ). Daneben sieht man die ganzen Thumbnails dieses Ordners (werden ebenfalls nach Beendigung von Paint aktualisiert), dort sind die Änderungen nicht ersichtlich, im Windows Explorer auch nicht, wenn ich das Bild aber öffne, sind die Striche da. Ich glaube bei mir spukt es. Bei Bearbeitung der Bilder im Photoshop kann ich beim Abspeichern entscheiden ob das vorschaubild auch aktualisiert wird. Irgendwo muss da mein Paint einen Fehler haben.

Soll ich jetzt immer wenn ich ein Bild im Paint bearbeite mit Hilfe von GDI+ ein neues Vorschaubild erzeugen? Ist das nicht etwas aufwendig? irgendwo muss doch ein Fehler sein. Verdammt!!!

Matthias

Kommentar von Frank Schüler am 25.10.2006 um 14:46

Hi

Bei mir funtioniert alles. Nach dem ändern des Bildes mit Paint wird sowohl das Thumb, mit den Änderungen, im Explorer als auch mit diesem Code korrekt angezeigt.

Könnte es sein das Du von den Vorschaubildern sprichst, die sich in JPEGs befinden können (EXIF Vorschaubild)?

MFG Frank

Kommentar von Waibel Matthias am 25.10.2006 um 13:27

Irgendwie wird bei Paint das Thumb nicht aktualisiert, bei, Photoshop klappts einwandfrei....

Keine Ahnung wieso


Danke für die Hilfe

mfg Matthias

Kommentar von Waibel Matthias am 25.10.2006 um 13:23

Mittlerweile habe ich bemerkt, dass auch der Explorer in diesem fall das bild nicht aktualisiert.. kann das sein?

Kommentar von Waibel Matthias am 25.10.2006 um 13:19

Ich habe es gespeichert, ernuet ausgelesen und es hat nicht funktioniert. sogar als ich das programm neu gestartet habe...

Kommentar von Frank Schüler am 25.10.2006 um 13:02

Wenn Du das Bild in Paint bearbeitest und speicherst nachdem Du das Vorschaubild ausgelesen hast, musst Du das Bild erneut einlesen um die Änderungen im Vorschaubild zu sehen.

MFG Frank

Kommentar von Matthias Waibel am 25.10.2006 um 12:43

Hallo
Es ist wirklich ein super Code. Extrem schnelle Anzeige eines Miniaturbildes. Nur gibt es ein Problem das ich nicht lösen kann:

Wenn ich ein Bild bspw. mit Paint bearbeite, werden diese Änderungen in der Miniaturansicht nicht übenommen? Wie kann ich die Miniaturansicht aktualisieren??

DANKE

Matthias

Kommentar von Frank Schüler am 21.02.2006 um 20:50

Hallo Joe

Wie oben schon erwähnt, bietet die Funktion "GdipGetImageThumbnail" keine vernünftige Interpolation an. Da müsstest Du Dir den Tipp 0658 ansehen. Bei diesem Tipp kannst Du diverse Interpolationsmöglichkeiten einstellen zb. Antialias, Smoothing, Bicubic, Bilinear usw.

Kommentar von Joe am 21.02.2006 um 09:38

Die Qualitaet des Thumbnail ist ziemlich schlecht. Kann man das nicht verbessern ?

Kommentar von Christoph Basedau am 08.10.2005 um 23:16

Ganz hübsch, allerdings funktioniert das Zoomen der Thumbnails über den Regler nicht "on-the-fly". Der neue Wert wird erst angewendet, wenn man ein neues Bild öffnet.
Einfache Abhilfe: Den Dateipfad aus ComDlg in modulvaraible
(z.B "mstrFile") speichern und in HScroll1_Change()
dann das Bild entsprechend des neuen Scalings laden.
Dann verändert sich die Bildgrösse sozusagen "live" mit dem Schieben des Reglers.



Option Explicit
Private m_strFile As String

...
..
.

Private Sub HScroll1_Change()
...
If mFile <> "" Then
Picture1.Picture = CreateThumbnailFromFile( _
m_strFile, HScroll1.Value)
End If
End Sub