用 Visual Basic 2005 构建一个简单的水印实用程序
关于用 Visual Basic 2005 构建一个简单水印实用程序的一篇文章。

引言
本文将介绍一种构建简单水印工具的方法,该工具可用于向任何支持的图像文件格式添加水印。生成的应用程序应允许用户将任何支持的图像文件格式打开到一个可滚动的图片框中,定义要用作水印的文本(提供默认版本),设置水印的字体和颜色,定义水印的不透明度,确定水印是否出现在图像的顶部或底部,并在将其保存到图像之前预览水印。

如果您对这张照片有任何好奇,它是美国金翅雀的,每年的这个时候,我大约有 50 只这样的鸟在我家的喂鸟器周围。我用我的 Fuji S700 数码相机隔着厨房的窗户拍下了这张照片。
入门
该解决方案包含一个名为 WatermarkingVB
的 Visual Basic 2005 中的 Windows Forms 项目;该应用程序只包含一个窗体 (frmWatermark.vb),并且驱动该应用程序的所有代码都包含在该单个 Form
类中。

代码:水印主窗体 (frmWatermark.vb)
此项目所需的所有代码都包含在此单个窗体中;该窗体将在本节中完全描述。
此 Form
类的代码从以下内容开始
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging
Imports System.Text
''' <summary>
''' An Image Watermarking Utility
''' </summary>
''' <remarks></remarks>
Public Class frmWatermark
在声明 Form
类之后,应用程序中的下一个任务是声明一个成员变量集合,这些变量需要具有窗体范围;这些变量包含在名为 Member Variables
的已定义 region
中。变量的声明如下;可以看出,这些变量用于跟踪当前文件位置和图像、用于将图像从一种格式转换为另一种格式的编解码器和编码器信息,以及用于显示图像水印的颜色和字体。
#Region "Member Variables"
Private CurrentFile As String
Private img As Image
Private myImageCodecInfo As ImageCodecInfo
Private myEncoder As System.Drawing.Imaging.Encoder
Private myEncoderParameter As EncoderParameter
Private myEncoderParameters As EncoderParameters
Private myWatermarkColor As System.Drawing.Color
Private myFont As System.Drawing.Font
#End Region
Form
类中的下一个代码块是构造函数;在这种情况下,构造函数用于建立默认配置,包括水印颜色的定义、水印的不透明度级别、定位选项(顶部或底部)、水印中包含的文本以及用于显示水印的字体。
#Region "Constructor"
''' <summary>
''' Constructor with default settings
''' </summary>
''' <remarks></remarks>
Public Sub New()
InitializeComponent()
' setup default settings
myWatermarkColor = Color.SteelBlue
cboOpacity.SelectedIndex = 2
optTop.Checked = True
txtWaterMark.Text = "Your Name " & _
Char.ConvertFromUtf32(169).ToString() & " " & _
DateTime.Now.Year.ToString() + ", All Rights Reserved"
myFont = txtWaterMark.Font
End Sub
#End Region
在构造函数之后,定义了一个区域来处理文件输入/输出操作。此区域包含两个事件处理程序,一个用于选择“打开文件”菜单项,另一个用于“保存”按钮的单击事件。“打开文件”菜单选项用于允许用户导航到并选择要加载的图像文件;所选图像文件将放置在可滚动的图片框中。
“保存”按钮的单击事件处理程序用于保存带有水印的图像文件;可以重命名或覆盖原始文件。
#Region "File IO"
Private Sub openToolStripMenuItem_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles openToolStripMenuItem.Click
' configure the open file dialog to point to some
' common (usable) image file formats
openFileDialog1.Title = "Open Image File"
openFileDialog1.Filter = "Bitmap Files|*.bmp" & _
"|Enhanced Windows MetaFile|*.emf" & _
"|Exchangeable Image File|*.exif" & _
"|Gif Files|*.gif|JPEG Files|*.jpg" & _
"|PNG Files|*.png|TIFF Files|*.tif|Windows MetaFile|*.wmf"
openFileDialog1.DefaultExt = "bmp"
openFileDialog1.FilterIndex = 1
openFileDialog1.FileName = ""
openFileDialog1.ShowDialog()
' if the user did not select a file, return
If (openFileDialog1.FileName = "") Then Return
' update the current file and form caption text
CurrentFile = openFileDialog1.FileName.ToString()
Me.Text = "Watermark Utility: " & CurrentFile.ToString()
Try
' open the image into the picture box
img = Image.FromFile(openFileDialog1.FileName, True)
picContainer.Image = img
' resize the picture box to support scrolling
' large images
picContainer.Size = img.Size
Catch ex As Exception
MessageBox.Show(ex.Message, "File Open Error")
End Try
End Sub
Private Sub btnSave_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnSave.Click
Try
' get the extension to figure out how to limit the save
' option to the current image file type
Dim strExt As String
strExt = System.IO.Path.GetExtension(CurrentFile)
strExt = strExt.ToUpper()
strExt = strExt.Remove(0, 1)
' if the current image is, for example, a GIF, only
' allow the user to save the file with the watermark
' as a GIF
SaveFileDialog1.Title = "Save File"
SaveFileDialog1.DefaultExt = strExt
SaveFileDialog1.Filter = strExt & " Image Files|*." + strExt
SaveFileDialog1.FilterIndex = 1
If SaveFileDialog1.ShowDialog() = DialogResult.OK Then
If (SaveFileDialog1.FileName = "") Then
Return
Else
' save the file with the name supplied by the user
picContainer.Image.Save(SaveFileDialog1.FileName)
End If
' update the current image file to point to the newly saved
' image
CurrentFile = SaveFileDialog1.FileName
Me.Text = "Watermark Utility: " + CurrentFile
MessageBox.Show(CurrentFile.ToString() + " saved.", "File
Save")
Else
MessageBox.Show("The save file request was cancelled by
user.", "Save Cancelled")
End If
Catch ex As Exception
MessageBox.Show(ex.Message.ToString(), "Image Save Error")
End Try
End Sub
#End Region
在处理完文件 IO 操作后,下一个代码区域是“图像格式转换”部分。在此区域中,提供的方法用于将打开的图像转换为其他格式(例如,将位图转换为 JPEG,或将 JPEG 转换为 GIF 等)。每个代码段都进行了注释,可以在以下内容中查看
#Region "Image Format Conversion"
Private Function GetEncoderInfo(ByVal mimeType As String) As ImageCodecInfo
Dim j As Integer
Dim encoders As ImageCodecInfo()
encoders = ImageCodecInfo.GetImageEncoders()
For j = 0 To encoders.Length
If (encoders(j).MimeType = mimeType) Then
Return encoders(j)
End If
Next
Return Nothing
End Function
Private Sub bitmapToolStripMenuItem_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles bitmapToolStripMenuItem.Click
' create a new name with the bitmap extension
Dim newName As String = _
System.IO.Path.GetFileNameWithoutExtension(CurrentFile)
newName = newName + ".bmp"
Try
' save the file as a bitmap
img.Save(newName, ImageFormat.Bmp)
CurrentFile = newName
picContainer.Image = Image.FromFile(CurrentFile)
Me.Text = "Watermark Utility: " + CurrentFile.ToString()
Catch
MessageBox.Show("Failed to save image to bitmap.", "Error", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End Try
MessageBox.Show("Image file saved to " + newName.ToString(), _
"Image Saved", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Private Sub emfToolStripMenuItem_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles emfToolStripMenuItem.Click
' create a new name with the EMF extension
Dim newName As String = _
System.IO.Path.GetFileNameWithoutExtension(CurrentFile)
newName = newName + ".emf"
Try
' save the file as a EMF
img.Save(newName, ImageFormat.Emf)
CurrentFile = newName
picContainer.Image = Image.FromFile(CurrentFile)
Me.Text = "Watermark Utility: " + CurrentFile.ToString()
Catch
MessageBox.Show("Failed to save image to EMF.", "Error", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End Try
MessageBox.Show("Image file saved to " + newName.ToString(), _
"Image Saved", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Private Sub exifToolStripMenuItem_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles exifToolStripMenuItem.Click
' create a new name with the EXIF extension
Dim newName As String = _
System.IO.Path.GetFileNameWithoutExtension(CurrentFile)
newName = newName + ".exif"
Try
' save the file as a EXIF
img.Save(newName, ImageFormat.Exif)
CurrentFile = newName
picContainer.Image = Image.FromFile(CurrentFile)
Me.Text = "Watermark Utility: " + CurrentFile.ToString()
Catch
MessageBox.Show("Failed to save image to EXIF.", "Error", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End Try
MessageBox.Show("Image file saved to " + newName.ToString(), _
"Image Saved", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Private Sub gIFFileToolStripMenuItem_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles gIFFileToolStripMenuItem.Click
' create a new name with the GIF extension
Dim newName As String = _
System.IO.Path.GetFileNameWithoutExtension(CurrentFile)
newName = newName + ".gif"
Try
' save the file as a GIF
img.Save(newName, ImageFormat.Gif)
CurrentFile = newName
picContainer.Image = Image.FromFile(CurrentFile)
Me.Text = "Watermark Utility: " + CurrentFile.ToString()
Catch
MessageBox.Show("Failed to save image to GIF.", "Error", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End Try
MessageBox.Show("Image file saved to " + newName.ToString(), _
"Image Saved", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Private Sub jPEGFileToolStripMenuItem_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) Handles _
jPEGFileToolStripMenuItem.Click
' create a new name with the JPEG extension
Dim newName As String = _
System.IO.Path.GetFileNameWithoutExtension(CurrentFile)
newName = newName + ".jpg"
Try
' save the file as a JPG
img.Save(newName, ImageFormat.Jpeg)
CurrentFile = newName
picContainer.Image = Image.FromFile(CurrentFile)
Me.Text = "Watermark Utility: " + CurrentFile.ToString()
Catch
MessageBox.Show("Failed to save image to JPEG.", "Error", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End Try
MessageBox.Show("Image file saved to " + newName.ToString(), _
"Image Saved", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Private Sub pNGFileToolStripMenuItem_Click(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles pNGFileToolStripMenuItem.Click
' create a new name with the PNG extension
Dim newName As String = _
System.IO.Path.GetFileNameWithoutExtension(CurrentFile)
newName = newName + ".png"
Try
' save the file as a png
img.Save(newName, ImageFormat.Png)
CurrentFile = newName
picContainer.Image = Image.FromFile(CurrentFile)
Me.Text = "Watermark Utility: " + CurrentFile.ToString()
Catch
MessageBox.Show("Failed to save image to PNG.", "Error", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End Try
MessageBox.Show("Image file saved to " + newName.ToString(), _
"Image Saved", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Private Sub tIFFFileToolStripMenuItem_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) Handles _
tIFFFileToolStripMenuItem.Click
' create a new name with the TIF extension
Dim newName As String = _
System.IO.Path.GetFileNameWithoutExtension(CurrentFile)
newName = newName + ".tif"
Try
' save the file as a tif
img.Save(newName, ImageFormat.Tiff)
CurrentFile = newName
picContainer.Image = Image.FromFile(CurrentFile)
Me.Text = "Watermark Utility: " + CurrentFile.ToString()
Catch
MessageBox.Show("Failed to save image to TIF.", "Error", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End Try
MessageBox.Show("Image file saved to " + newName.ToString(), _
"Image Saved", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Private Sub windowsMetafileToolStripMenuItem_Click(ByVal sender As _
System.Object, ByVal e As System.EventArgs) Handles _
windowsMetafileToolStripMenuItem.Click
' create a new name with the WMF extension
Dim newName As String = _
System.IO.Path.GetFileNameWithoutExtension(CurrentFile)
newName = newName + ".wmf"
Try
' save the file as a WMF
img.Save(newName, ImageFormat.Wmf)
CurrentFile = newName
picContainer.Image = Image.FromFile(CurrentFile)
Me.Text = "Watermark Utility: " + CurrentFile.ToString()
Catch
MessageBox.Show("Failed to save image to WMF.", "Error", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Return
End Try
MessageBox.Show("Image file saved to " + newName.ToString(), _
"Image Saved", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
#End Region
在图像转换例程之后,下一个代码区域用于执行实际的水印功能。
#Region "Watermarking"
''' <summary>
''' Display the watermark as it would appear after
''' the watermark were saved to the file
''' </summary>
''' <remarks></remarks>
Private Sub btnPreview_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles btnPreview.Click
' Update the application by reloading the image
picContainer.Image = Image.FromFile(CurrentFile)
Dim opac As Integer = 0
Dim sOpacity As String = cboOpacity.Text
' Determine the opacity of the watermark
Select Case (sOpacity)
Case "100%"
opac = 255 ' 1 * 255
Case "75%"
opac = 191 ' .75 * 255
Case "50%"
opac = 127 ' .5 * 255
Case "25%"
opac = 64 ' .25 * 255
Case "10%"
opac = 25 ' .10 * 255
Case Else
opac = 127 ' default at 50%; .5 * 255
End Select
' Get a graphics context
Dim g As Graphics = Graphics.FromImage(picContainer.Image)
' Create a solid brush to write the watermark text on the image
Dim myBrush As Brush
myBrush = New SolidBrush(Color.FromArgb(opac, myWatermarkColor))
' Calculate the size of the text
Dim sz As SizeF = g.MeasureString(txtWaterMark.Text, myFont)
' Create a copy of variables to keep track of the
' drawing position (X,Y)
Dim X As Integer
Dim Y As Integer
' Set the drawing position based on the users
' selection of placing the text at the bottom or
' top of the image
If (optTop.Checked = True) Then
X = Convert.ToInt32((picContainer.Image.Width - sz.Width) / 2)
Y = Convert.ToInt32((picContainer.Top + sz.Height) / 2)
Else
X = Convert.ToInt32((picContainer.Image.Width - sz.Width) / 2)
Y = Convert.ToInt32((picContainer.Image.Height - sz.Height))
End If
' draw the water mark text
g.DrawString(txtWaterMark.Text, myFont, myBrush, New Point(X, Y))
End Sub
Private Sub btnFont_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles btnFont.Click
' default the current font and color to that
' used in the watermark textbox
fontDialog1.ShowColor = True
fontDialog1.Font = txtWaterMark.Font
fontDialog1.Color = txtWaterMark.ForeColor
If fontDialog1.ShowDialog() <> DialogResult.Cancel Then
myFont = fontDialog1.Font
myWatermarkColor = fontDialog1.Color
txtWaterMark.Font = fontDialog1.Font
txtWaterMark.ForeColor = fontDialog1.Color
End If
End Sub
#End Region
这就是驱动水印工具所需的全部代码。通过提供的代码,可以将一种图像格式转换为另一种图像格式,并将用户定义的水印应用于现有的图像文件。
摘要
虽然本文旨在演示在 WinForms 实用程序应用程序的上下文中对图像文件进行水印处理的方法;但可以修改项目中使用的代码以批量处理图像文件,或以编程方式对图像文件进行水印处理,而无需用户干预。即使用作实用程序,该应用程序对于任何希望在 Web 上展示图像文件之前对其进行水印或添加标题的人也可能具有一定的价值。