Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all articles
Browse latest Browse all 1448

[VB6] Shell Video Thumbnail Images

$
0
0
Summary

Thumbnail images for video files are accessible via Shell32's Automation (i.e. ActiveX) interface.

These can be obtained using a ShellFolderItem object's ExtendedProperty() method. The tough part is that these are returned as PROPVARIANT values and not regular Variants as we know them in VB6. For many ExtendedProperty() return values VB6 can handily coerce the PROPVARIANT to a Variant, even though you can still end up with unsupported subtypes (like unsigned integers of varying lengths).

Here we need to request the property by passing SCID_THUMBNAILSTREAM to ExtendedProperty. In this case it returns a PROPVARIANT with a VT_STREAM content subtype, making it a bit troublesome in that VB6 cannot convert it to a standard Variant.

Luckily that can be done by calling the PropVariantToVariant function, though it handles the situation by converting the VT_STREAM to a Variant's VT_UNKNOWN. Still, the IStream object reference is there and usable.

This particular stream is designed for consumption by GDI+/WindowsCodecs, and isn't a simple PNG or JPEG in a stream. But GdipCreateBitmapFromStream() can read it just fine, and from there you are on your way.


The Code

Most of the code in the sample program relates to a version of my ThumbnailsView UserControl. Without this the program would be a lot smaller, but we don't have many good controls for multi-image display. You almost always end up working with things like nested PictureBox controls and a scrollbar or two and some logic to glue it all together. There is also a funky SimpleProgressBar UserControl for visual feedback.

You can pretty much ignore both of those along with helper modules Picture2BMP.bas, BmpGen.cls, and ScaledLoader.cls that are used by ThumbnailsView.ctl.

Even Form1's code is mostly gingerbread, dealing with picking a folder of video files to fetch thumbnails for. Its ListAttributes() subroutine is the part that enumerates the folder items and retrieves the thumbnails, with the help of GdipLoader.cls to convert the stream into a StdPicture object.

Code:

Private Sub ListAttributes(ByVal FolderPath As String)
    Dim Folder As Shell32.Folder
    Dim ShellFolderItem As Shell32.ShellFolderItem
    Dim GdipLoader As GdipLoader
    Dim ExtProp As Variant

    Set Folder = ShellObject.NameSpace(FolderPath & "\")
    If Folder Is Nothing Then
        Unload Me
    Else
        Set GdipLoader = New GdipLoader
        With SimpleProgressBar1
            .Caption = ""
            .Max = Folder.Items.Count
        End With

        For Each ShellFolderItem In Folder.Items
            If Not (ShellFolderItem.IsFolder Or ShellFolderItem.IsLink) Then
                PropVariantToVariant ShellFolderItem.ExtendedProperty(SCID_THUMBNAILSTREAM), ExtProp
                'Note: vbDataObject value is really VT_UNKNOWN (i.e. 13):
                If VarType(ExtProp) = vbDataObject Then
                    ThumbnailsView1.Add GdipLoader.LoadPictureStream(ExtProp), ShellFolderItem.Name
                End If
            End If
            SimpleProgressBar1.Value = SimpleProgressBar1.Value + 1
        Next
    End If
End Sub


Issues

The first issue is that this isn't speedy. I'm not sure what Shell32 is going through to get thethumbnails even though I had assumed they were retrieved using typical OLE Storages & Streams mechanisms. It almost seems too slow for that though and since it uses video codecs there must be more involved.

The second issue is that depending on the video encoding format and codecs you have installed you might get nice results or a junk image back. I was almost ready to give it up until I realized I had VB6.exe in ffdshow's blacklist on my development PC.

But testing the compiled EXE (and allowing ffdshow use via the Compatibility Manager popup) returned good images from everything I tested but some DIVX formats.

See: ffdshow tryouts or use a search site.

Requirements

As written, the program requires a number of things, including running on Windows XP SP2 or later:

  • GDI+ version 1 - ships in XP and later, deployable back to Win95.
  • PropVariantToVariant() in propsys.dll - requires XP SP2 or later.
  • Microsoft Windows Image Acquisition Library v2.0 - ships in Vista or later, can be added to XP SP1 or later.
  • Edanmo's OLE interfaces and functions typelib (olelib.tlb) - needed for development, not needed at run time. Can be acquired from http://www.mvps.org/emorcillo/en/index.shtml.


By getting rid of ThumbnailsView and using some other multi-image control and associated code you can eliminate WIA 2.0 and Edanmo's olelib.tlb.


The Demo

Running the program you'll see the single Form user interface. It has a status/progress bar, a ThumbnailsView taking up the rest of the Form, and a single menu item "Choose Folder" you use to start the process.

The running progress shows you the current and total folder items being processed. Subfolders and links are skipped, as are files that do not have a ThumbnailStream return value.


Name:  sshot1.jpg
Views: 116
Size:  38.3 KB
Some videos using standard Windows codecs


Name:  sshot3.jpg
Views: 117
Size:  43.6 KB
Some videos that require additional codecs (MP4 mostly).
Work fine when ffdshow is used.


Remaining Issues

In theory all kinds of files ought to return thumbnails this way. However I get nothing useful for music folders, Word document folders, etc. I can only assume that the returned results are in another format this demo rejects (GDI+ Image object?). I'll have to investigate further.
Attached Images
  
Attached Files

Viewing all articles
Browse latest Browse all 1448

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>