带预览功能的图像查看器用户控件
本文讨论了一个图像查看器用户控件的构建,该控件可用于显示包含图像文件集合的目录中的图像。

引言
本文讨论了一个图像查看器用户控件的构建,该控件可用于显示包含图像文件集合的目录中的图像。该控件显示文件中的上一张和下一张图像以及当前图像。可以根据用户计算机的文件关联,从用户控件中打开当前图像到用户计算机上的默认图像应用程序。图像缩略图用于提供目录中的上一张、当前张和下一张图像。如演示所示,用户控件可以添加到需要允许用户在打开图像进行查看或编辑之前预览或视觉扫描图像的应用程序中。

(显示 Microsoft Office Picture Manager)。
入门
要开始,请解压缩包含的项目并在 Visual Studio 2008 环境中打开解决方案。解决方案包含两个项目。ImageViewerVB
是第一个项目,它是一个控件库项目,包含一个用户控件。第二个项目(TestImageViewerVB
)是一个测试应用程序,显示一个用于容纳用户控件的单个窗体。
在解决方案资源管理器中,您应该会注意到这些文件

图像查看器用户控件 (ImageViewerVB.vb)
图像查看器用户控件包含浏览图像文件夹和查看当前、下一张和上一张图像所需的所有内容。控件本身包含一个文本框和一个浏览按钮,用于打开文件夹浏览器对话框;当用户导航到所需文件夹并选择它时,文件夹的路径将显示在 `textbox` 控件中,并且浏览按钮的点击事件处理程序将触发收集所选文件夹中包含的所有图像文件,并开始显示图像。控件包含三个图片框,用于显示上一张、当前张和下一张图像。上一张和下一张图像旁边有两个按钮,用于在图像集合中向后和向前移动。每个图像文件的路径都包含在一个 ArrayList 中,并且一个具有类作用域的整数值用于维护该 ArrayList 中的当前位置。
如果您愿意在 IDE 中打开代码视图,您会看到代码文件以以下 using 语句开头;大多数包含项都是按默认配置的,但添加了 System.IO
以支持代码中使用的目录操作。
Imports System.IO
Imports System.Collections
在 `imports` 之后,定义了类并添加了构造函数,以及用于维护文件夹路径、图像文件路径(在 ArrayList 中)、图像列表位置和图像本身(上一张、当前张和下一张)的一组本地成员变量。我在这里的构造函数中什么也没做,但如果您愿意,例如,您可能希望将文件夹浏览器对话框指向一个默认文件夹位置。
Public Class ImageViewer
' private member variables
Private mFolder As String
Private mImageList As ArrayList
Private mImagePosition As Integer
Private mPreviousImage As Image
Private mCurrentImage As Image
Private mNextImage As Image
''' <summary>
''' Default Constructor
''' </summary>
''' <remarks></remarks>
Public Sub New()
' This call is required by the Windows Form Designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
接下来是用户控件的加载事件处理程序;此演示在加载事件中不执行任何操作,但您可能希望使用此处理程序在此处执行某些操作。
''' <summary>
''' Default load event handler
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub ImageViewer_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
' do nothing
End Sub
代码的下一部分是浏览按钮的点击事件处理程序。在此代码部分中,处理程序打开文件夹浏览器对话框,用户可以使用该对话框设置图像文件夹的路径。文件夹设置后,处理程序会遍历该文件夹并查找所有 BMP、JPEG 和 GIF 文件;找到的任何图像文件的文件路径都会添加到 ArrayList 中(BMP、GIF 和 JPEG)。一旦 ArrayList 中填充了文件路径,点击事件处理程序将通过将列表索引位置设置为零来完成,然后调用 SetImages
方法,该方法将当前、上一张和下一张图像设置到相应的图片框中。代码已注释,应该很容易理解。
''' <summary>
''' Open the folder browse dialog and load
''' the initial images
''' </summary>
''' <remarks></remarks>
Private Sub btnBrowse_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnBrowse.Click
' Label the folder browser dialog
Me.folderBrowserDialog1.Description = "Select the image directory."
' disable create folder feature of folder browser
Me.folderBrowserDialog1.ShowNewFolderButton = False
' display the folder browser
Dim result As DialogResult = folderBrowserDialog1.ShowDialog()
If result = DialogResult.OK Then
' on okay, set the image folder to the
' folder browser's selected path
mFolder = folderBrowserDialog1.SelectedPath
If (Not String.IsNullOrEmpty(mFolder)) Then
txtImageDirectory.Text = mFolder
Else
' exit if the user cancels
Return
End If
' initialize the image arraylist
mImageList = New ArrayList()
' loop through the image directory
' and find all of the image files
' add the found files to the image
' list - add other image types if
' necessary
Dim Dir As New DirectoryInfo(mFolder)
Dim f As FileInfo
For Each f In Dir.GetFiles("*.*")
Select Case (f.Extension.ToUpper())
Case ".JPG"
mImageList.Add(f.FullName)
Case ".BMP"
mImageList.Add(f.FullName)
Case ".GIF"
mImageList.Add(f.FullName)
Case Else
' skip file
End Select
Next
' set the starting position to 0
' and call the set images method
' to load the pictures
mImagePosition = 0
SetImages()
End If
End Sub
下一段代码是 SetImages
函数;此函数用于为每个图片框设置图像(上一张、当前张和下一张图像)。此代码创建存储在图像 ArrayList 中的文件路径的图像的缩略图,然后将图片框设置为显示缩略图而不是完整图像。代码的编写方式是在达到用于存储实际图像文件路径的 ArrayList 的限制时做出不同的响应;在限制处,上一张或下一张图像将被清空。
此外,代码会在设置图片框后清除图像,并且每次调用函数时都会调用垃圾回收来清理。我发现,如果没有垃圾回收,当一次扫描大量图像时,控件会抛出内存不足异常。同样,此代码已注释,应该很容易理解。
''' <summary>
''' This function is used to set the previous,
''' current, and next images into the
''' correct picture boxes
''' </summary>
''' <remarks></remarks>
Private Sub SetImages()
' clear any existing images
' memory will be an issue if
' cycling through a large
' number of images
mPreviousImage = Nothing
mNextImage = Nothing
mCurrentImage = Nothing
' set the previous image
If mImagePosition > 0 Then
Try
' set delegate
Dim prevCallback As Image.GetThumbnailImageAbort = _
New Image.GetThumbnailImageAbort(AddressOf ThumbnailCallback)
' get the previous image
Dim prevBmp As _
New Bitmap(mImageList(mImagePosition - 1).ToString())
' thumbnail the image to the size
' of the picture box
mPreviousImage = _
prevBmp.GetThumbnailImage(160, 100, _
prevCallback, IntPtr.Zero)
' set the picture box image
picPreviousImage.Image = mPreviousImage
' clear everything out
prevBmp = Nothing
prevCallback = Nothing
mPreviousImage = Nothing
Catch
'stall if it hangs, the user can retry
End Try
Else
' at the limit clear the
' image
picPreviousImage.Image = Nothing
End If
' set current image
If mImagePosition < mImageList.Count Then
Try
' set delegate
Dim currentCallback = _
New Image.GetThumbnailImageAbort(AddressOf
ThumbnailCallback)
' get the current image
Dim currentBmp As _
New Bitmap(mImageList(mImagePosition).ToString())
' thumbnail the image to the size
' of the picture box
mCurrentImage = _
currentBmp.GetThumbnailImage(320, 200, currentCallback,
IntPtr.Zero)
' set the picture box image
picCurrentImage.Image = mCurrentImage
' clear everything out
currentBmp = Nothing
mCurrentImage = Nothing
currentCallback = Nothing
Catch
'stall if it hangs, the user can retry
End Try
End If
' set next image
If mImagePosition < mImageList.Count - 1 Then
Try
' set delegate
Dim nextCallback As _
New Image.GetThumbnailImageAbort(AddressOf
ThumbnailCallback)
' get the next image
Dim nextBmp As _
New Bitmap(mImageList(mImagePosition + 1).ToString())
' thumbnail the image to the size
' of the picture box
mNextImage = _
nextBmp.GetThumbnailImage(160, 100, nextCallback,
IntPtr.Zero)
' set the picture box image
picNextImage.Image = mNextImage
' clear everything out
nextBmp = Nothing
nextCallback = Nothing
mNextImage = Nothing
Catch
'stall if it hangs, the user can retry
End Try
Else
' at the limit clear the
' image
picNextImage.Image = Nothing
End If
' call for garbage collection
GC.Collect()
End Sub
下一段代码是缩略图尝试中止时调用的代码;这是生成缩略图所需的方法。
''' <summary>
''' Thumbnail image abort target
''' </summary>
''' <returns></returns>
''' <remarks></remarks>
Public Function ThumbnailCallback() As Boolean
Return False
End Function
上一张图像按钮的点击事件处理程序紧随其后;它用于更新 ArrayList 中的图像位置,并在更新索引位置时重新调用 SetImages
方法。
''' <summary>
''' Set the image position and reset all
''' of the images when the previous image
''' button is clicked
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnPreviousImage_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles btnPreviousImage.Click
If (mImagePosition >= 0 And Not picPreviousImage.Image Is Nothing)
Then
mImagePosition -= 1
SetImages()
End If
End Sub
下一张图像按钮的点击事件处理程序紧随其后;它用于更新 ArrayList 中的图像位置,并在更新索引位置时重新调用 SetImages
方法。
''' <summary>
''' Set the image position and reset all
''' of the images when the next image
''' button is clicked
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnNextImage_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnNextImage.Click
If (mImagePosition <= (mImageList.Count - 2)) Then
mImagePosition += 1
SetImages()
End If
End Sub
最后一个方法是根据计算机的文件关联,将当前图像打开到默认图像查看应用程序中。此方法仅调用进程启动函数,并将当前图像文件的文件路径传递给它。
''' <summary>
''' Open the current image using the default
''' program per the user's file associations
''' </summary>
''' <param name="sender"></param>
''' <param name="e"></param>
''' <remarks></remarks>
Private Sub btnOpenImage_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btnOpenImage.Click
System.Diagnostics.Process.Start(
_mImageList(mImagePosition).ToString())
End Sub
文本窗体 (Form1.vb)
测试应用程序中包含的测试窗体包含一个 Image Viewer 用户控件的实例;窗体本身没有特定代码,因此这里没有什么可以报告的。测试应用程序被设置为启动项目,并且在执行时,测试窗体打开并显示用户控件。
摘要
此解决方案提供了一个用户控件,可用于提供用户界面,如果应用程序用户需要浏览图像文件,该界面可能会有所帮助。用户控件提供了浏览包含图像的文件夹所需的控件,以及预览当前选定、上一张和下一张图像的方法。通过该控件,最终用户可以浏览文件夹中包含的所有图像文件,并在需要时将所有图像打开到新应用程序中。
历史
- 2008年6月3日:初始版本