快速在PictureBox中加载图片

3

我有一个程序,可以在小的图片框中显示jpg的预览图。这些图像的加载速度很慢,每个图像几乎需要一秒钟的时间。这是因为这些图像很大(8/9 MB)。我需要快速加载它们,例如通过加载图片的缩略图。我希望避免将所有内容都放入内存中,因为可能会有数百张图片。

您对此有什么建议?

谢谢


它可能很慢,因为每个图像都被图片框调整大小,而调整大小是一个CPU密集型操作。适当大小的缩略图无疑会解决这个问题。你是通过网络获取图像吗?如果是这样,请让你的服务器生成缩略图。 - dandan78
不,它在本地驱动器上... - sharkyenergy
1个回答

1

您需要提前调整图片大小。

创建缩略图同样会很慢,因为您需要先读取整个文件,然后才能开始制作缩略图。

您可以像Windows一样创建一个缩略图数据库,为每个图片存储缩略图,只有在需要时才使用完整尺寸的图片。

因此,如果您有像这样的情况,

picture001.jpg
picture002.jpg
picture003.jpg

为每个创建缩略图;
picture001.jpg
picture001_tumb.jpg
picture002.jpg
picture002_tumb.jpg
picture003.jpg
picture003_tumb.jpg

在加载图片时,如果有_tumb.jpg,则检测是否存在,如果不存在则创建并存储。当然,需要在后台工作器中完成此操作,因为您需要使主应用程序响应...

您还可以使用此代码从Windows Shell请求图标;

Imports System.Runtime.InteropServices
Imports System
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Collections.Generic
Imports System.Text

' http://www.vbforums.com/showthread.php?617626-How-do-I-extract-a-256X256-image-out-of-an-icon&highlight=IShellItemImageFactory

Module GetShellIcon
    <Flags()> _
    Public Enum SIIGBF
        SIIGBF_RESIZETOFIT = 0
        SIIGBF_BIGGERSIZEOK = 1
        SIIGBF_MEMORYONLY = 2
        SIIGBF_ICONONLY = 4
        SIIGBF_THUMBNAILONLY = 8
        SIIGBF_INCACHEONLY = 16
    End Enum

    Public Enum SIGDN As UInteger
        NORMALDISPLAY = 0
        PARENTRELATIVEPARSING = &H80018001UI
        PARENTRELATIVEFORADDRESSBAR = &H8001C001UI
        DESKTOPABSOLUTEPARSING = &H80028000UI
        PARENTRELATIVEEDITING = &H80031001UI
        DESKTOPABSOLUTEEDITING = &H8004C000UI
        FILESYSPATH = &H80058000UI
        URL = &H80068000UI
    End Enum

    <ComImportAttribute(), GuidAttribute("bcc18b79-ba16-442f-80c4-8a59c30c463b"),     InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)> _
    Public Interface IShellItemImageFactory
        Sub GetImage(ByVal size As SIZE, ByVal flags As SIIGBF, ByRef phbm As IntPtr)
    End Interface

    <ComImport()> <Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")>     <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
    Public Interface IShellItem
        Sub BindToHandler(ByVal pbc As IntPtr, <MarshalAs(UnmanagedType.LPStruct)>     ByVal bhid As Guid, <MarshalAs(UnmanagedType.LPStruct)> ByVal riid As Guid, ByRef ppv As     IntPtr)
        Sub GetParent(ByRef ppsi As IShellItem)
        Sub GetDisplayName(ByVal sigdnName As SIGDN, ByRef ppszName As IntPtr)
        Sub GetAttributes(ByVal sfgaoMask As UInt32, ByRef psfgaoAttribs As UInt32)
        Sub Compare(ByVal psi As IShellItem, ByVal hint As UInt32, ByRef piOrder As     Integer)
    End Interface

    <DllImport("shell32.dll", CharSet:=CharSet.Unicode, PreserveSig:=False)> _
    Public Sub SHCreateItemFromParsingName(<MarshalAs(UnmanagedType.LPWStr)> ByVal     pszPath As String, ByVal pbc As IntPtr, <MarshalAs(UnmanagedType.LPStruct)> ByVal riid As     Guid, <MarshalAs(UnmanagedType.Interface, IidParameterIndex:=2)> ByRef ppv As IShellItem)
    End Sub

    <StructLayout(LayoutKind.Sequential)> _
    Public Structure SIZE
        Public cx As Integer
        Public cy As Integer
        Public Sub New(ByVal cx As Integer, ByVal cy As Integer)
            Me.cx = cx
            Me.cy = cy
        End Sub
    End Structure

    Public Function GetShellIcon(ByVal Path As String, MySIIGBF As SIIGBF, Optional ByVal Width As Integer = 256, Optional ByVal Height As Integer = 256) As Bitmap

        Dim ppsi As IShellItem = Nothing
        Dim hbitmap As IntPtr = IntPtr.Zero
        Dim uuid As New Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")

        Dim bs As Bitmap

        SHCreateItemFromParsingName(Path, IntPtr.Zero, uuid, ppsi)
        DirectCast(ppsi, IShellItemImageFactory).GetImage(New SIZE(Width, Height), MySIIGBF, hbitmap)
        bs = System.Drawing.Bitmap.FromHbitmap(hbitmap)
        bs.MakeTransparent(Color.Black)

        Return bs

    End Function

End Module

有道理...这个问题是否有解决方案? - sharkyenergy
谢谢,有没有Windows命令可以自动完成这个操作?或者读取它们?我是指使用Windows标准。如果我让驱动器充满缩略图,用户会杀了我的。 - sharkyenergy
当然,最好的方法是连接到现有系统。我知道Windows会创建一个tumb_db文件,其中包含该文件夹中每个图像的缩略图。您可以尝试找出一种读取Windows tumb数据库的方法...这样您就不必重新发明轮子 :) - Dennis
Windows的缩略图系统是否可访问? - sharkyenergy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接