You can use the below code to create a SDK script activity to apply a dynamic stamp. Make sure to add the 3 needed Import statements at the top of the activity code. Then set your default values for the stamp in the first 7 lines of code of the Execute() function (line number 24 - 30). You could use tokens to pass in the defaults if you wanted.
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Data.SqlClient
Imports System.Text
Imports System.Drawing ' Add
Imports System.Drawing.Imaging ' Add
Imports System.Runtime.InteropServices ' Add
Imports Laserfiche.RepositoryAccess
Namespace WorkflowActivity.Scripting.SDKScript
'''<summary>
'''Provides one or more methods that can be run when the workflow scripting activity is performed.
'''</summary>
Public Class Script1
Inherits RAScriptClass102
Private sErrorMsg as String = Nothing
'''<summary>
'''This method is run when the activity is performed.
'''</summary>
Protected Overrides Sub Execute()
'Write your code here. The BoundEntryInfo property will access the entry, RASession will get the Repository Access session
Dim sStampName As String = "ApprovedDateStamp" ' Name of stamp to apply to document.
Dim iMaxW As Integer = 2000 ' Maximum width of stamp
Dim iPageNumber As Integer = 1 ' Page number where stamp is applied
Dim iStampLeft As Integer = 600 ' How far from the left edge to place the stamp
Dim iStampTop As Integer = 50 ' How far from the top edge to place the stamp
Dim fScale As Single = 0.3 ' Stamp scale factor
Dim StampColor As Laserfiche.RepositoryAccess.Common.LfColor = Laserfiche.RepositoryAccess.Common.LfColor.BLUE ' Sets stamp fill color
If BoundEntryInfo.EntryType = EntryType.Document Then
Try
Dim StampImage As Bitmap = CreateStampImage(sStampName, iMaxW)
Dim iW As Integer = StampImage.Width
Dim iH As Integer = StampImage.Height
Using docinfo As DocumentInfo = DirectCast(BoundEntryInfo, DocumentInfo)
docinfo.Lock(LockType.Exclusive)
Dim DynamicStamp As StampInfo = New StampInfo(RASession)
DynamicStamp.Name = sStampName & "_temp"
Dim SourceByteArray() As Byte = BmpToByte(StampImage)
Dim StampBytes(SourceByteArray.Length - 15) As Byte
Array.Copy(SourceByteArray, 14, StampBytes, 0, StampBytes.Length - 1)
DynamicStamp.ImageData = StampBytes
DynamicStamp.UpdateImageData()
Dim BCStampAnnotation As New StampAnnotation(docinfo, iPageNumber, DynamicStamp)
BCStampAnnotation.Position = New Laserfiche.RepositoryAccess.Common.LfPoint(iStampLeft, iStampTop)
BCStampAnnotation.Color = StampColor
Dim StampRect As Laserfiche.RepositoryAccess.Common.LfRectangle = BCStampAnnotation.Coordinates
StampRect.Width = iW * fScale
StampRect.Height = iH * fScale
StampRect.Location = New Laserfiche.RepositoryAccess.Common.LfPoint(iStampLeft, iStampTop)
BCStampAnnotation.Coordinates = StampRect
docinfo.GetPageInfo(iPageNumber).AddAnnotation(BCStampAnnotation)
docinfo.Save()
docinfo.Unlock()
End Using
StampImage.Dispose()
Catch ex As Exception
sErrorMsg = ex.Message
WorkflowApi.TrackError(ex.Message)
End Try
End If
If Not String.IsNullOrEmpty(sErrorMsg) Then
SetTokenValue("Error", sErrorMsg)
End If
End Sub
Private Function BmpToByte(ByVal bmp As Bitmap) As Byte()
Dim byteReturn() As Byte
Using memStream As System.IO.MemoryStream = New System.IO.MemoryStream
bmp.Save(memStream, System.Drawing.Imaging.ImageFormat.Bmp)
byteReturn = memStream.ToArray()
End Using
bmp.Dispose()
Return byteReturn
End Function
Private Function PublicStampList() As List(Of String)
Dim lstReturn As New List(Of String)
Try
Using PublicStampInfoReader As StampInfoReader = Stamp.EnumPublicStamps(RASession)
While PublicStampInfoReader.Read()
Dim CurStamp As StampInfo = PublicStampInfoReader.Item()
lstReturn.Add(CurStamp.Name)
End While
End Using
Catch ex As Exception
sErrorMsg = ex.Message
End Try
Return lstReturn
End Function
Private Function PersonalStampList() As List(Of String)
Dim lstReturn As New List(Of String)
Try
Using PersonalStampInfoReader As StampInfoReader = Stamp.EnumPersonalStamps(RASession)
While PersonalStampInfoReader.Read()
Dim CurStamp As StampInfo = PersonalStampInfoReader.Item()
lstReturn.Add(CurStamp.Name)
End While
End Using
Catch ex As Exception
sErrorMsg = ex.Message
End Try
Return lstReturn
End Function
Private Function StampIDbyName(ByVal sName As String) As Integer
Dim iReturn As Integer = -1
Try
Using PersonalStampInfoReader As StampInfoReader = Stamp.EnumPersonalStamps(RASession)
While PersonalStampInfoReader.Read()
Dim CurStamp As StampInfo = PersonalStampInfoReader.Item()
If CurStamp.Name = sName Then
iReturn = CurStamp.Id
Exit While
End If
End While
End Using
If iReturn = -1 Then
Using PublicStampInfoReader As StampInfoReader = Stamp.EnumPublicStamps(RASession)
While PublicStampInfoReader.Read()
Dim CurStamp As StampInfo = PublicStampInfoReader.Item()
If CurStamp.Name = sName Then
iReturn = CurStamp.Id
Exit While
End If
End While
End Using
End If
Catch ex As Exception
sErrorMsg = ex.Message
iReturn = -1
End Try
Return iReturn
End Function
Private Function ReplaceStampTokens(ByVal StampText As String) As String
Dim sReturn As String = StampText
Try
If sReturn.Contains("%(Date)") Then
sReturn = sReturn.Replace("%(Date)", DateTime.Now.ToShortDateString)
End If
'If sReturn.Contains("%(Count)") Then
' sReturn = sReturn.Replace("%(Count)", "Count To Do")
'End If
'If sReturn.Contains("%(GCount)") Then
' sReturn = sReturn.Replace("%(GCount)", "GCount To Do")
'End If
If sReturn.Contains("%(UserName)") Then
sReturn = sReturn.Replace("%(UserName)", GetTokenValue("Initiator").ToString())
End If
If sReturn.Contains("%(ParentName)") Then
Dim sParentName As String
Using Parent As FolderInfo = Folder.GetFolderInfo(BoundEntryInfo.ParentId, RASession)
sParentName = Parent.Name
End Using
sReturn = sReturn.Replace("%(ParentName)", sParentName)
End If
If sReturn.Contains("%(Id)") Then
sReturn = sReturn.Replace("%(Id)", BoundEntryId.ToString())
End If
If sReturn.Contains("%(ParentId)") Then
sReturn = sReturn.Replace("%(ParentId)", BoundEntryInfo.ParentId.ToString())
End If
Catch ex As Exception
sErrorMsg = ex.Message
sReturn = StampText
End Try
Return sReturn
End Function
Private Function Convert_Text_to_Image(ByVal txt As String, ByVal fontname As String, ByVal fStyle As FontStyle, ByVal ifontsize As Integer, ByVal iMaxWidth As Integer) As Bitmap
If String.IsNullOrEmpty(txt) Then
txt = " "
End If
'creating bitmap image
Dim bmp As New Bitmap(100, 100)
'bmp.SetResolution(300, 300)
'FromImage method creates a new Graphics from the specified Image.
Dim grfx As Graphics = Graphics.FromImage(bmp)
' Create the Font object for the image text drawing.
Using fnt As Font = New Font(fontname, ifontsize, fStyle)
' Instantiating object of Bitmap image again with the correct size for the text and font.
Dim stringSize As SizeF = grfx.MeasureString(txt, fnt)
Dim iProjWidth As Integer = Convert.ToInt32(stringSize.Width)
If iProjWidth > iMaxWidth Then
iProjWidth = iMaxWidth
End If
bmp = New Bitmap(bmp, iProjWidth, Convert.ToInt32(stringSize.Height))
'bmp.SetResolution(300, 300)
grfx = Graphics.FromImage(bmp)
'Draw Specified text with specified format
grfx.DrawString(txt, fnt, Brushes.Black, 0, 0)
End Using
'font.Dispose()
grfx.Flush()
grfx.Dispose()
'return Bitmap Image
Return bmp
End Function
Private Function Superimpose(ByVal largeBmp As Bitmap, ByVal smallBmp As Bitmap, ByVal TopOffset As Integer, ByVal iLeftMargin As Integer) As Bitmap
Dim g As Graphics = Graphics.FromImage(largeBmp)
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver
smallBmp.MakeTransparent()
Dim x As Integer = iLeftMargin
Dim y As Integer = TopOffset
g.DrawImage(smallBmp, New Point(iLeftMargin, TopOffset))
Return largeBmp
End Function
Private Function ConvertToBitonal(ByVal original As Bitmap) As Bitmap
Dim source As Bitmap = Nothing
' If original bitmap is not already in 32 BPP, ARGB format, then convert
If original.PixelFormat <> PixelFormat.Format32bppArgb Then
source = New Bitmap(original.Width, original.Height, PixelFormat.Format32bppArgb)
source.SetResolution(original.HorizontalResolution, original.VerticalResolution)
Using g As Graphics = Graphics.FromImage(source)
g.DrawImageUnscaled(original, 0, 0)
End Using
Else
source = original
End If
' Lock source bitmap in memory
Dim sourceData As BitmapData = source.LockBits(New Rectangle(0, 0, source.Width, source.Height), ImageLockMode.[ReadOnly], PixelFormat.Format32bppArgb)
' Copy image data to binary array
Dim imageSize As Integer = sourceData.Stride * sourceData.Height
Dim sourceBuffer As Byte() = New Byte(imageSize - 1) {}
Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize)
' Unlock source bitmap
source.UnlockBits(sourceData)
' Create destination bitmap
Dim destination As New Bitmap(source.Width, source.Height, PixelFormat.Format1bppIndexed)
destination.SetResolution(original.HorizontalResolution, original.VerticalResolution)
' Lock destination bitmap in memory
Dim destinationData As BitmapData = destination.LockBits(New Rectangle(0, 0, destination.Width, destination.Height), ImageLockMode.[WriteOnly], PixelFormat.Format1bppIndexed)
' Create destination buffer
imageSize = destinationData.Stride * destinationData.Height
Dim destinationBuffer As Byte() = New Byte(imageSize - 1) {}
Dim sourceIndex As Integer = 0
Dim destinationIndex As Integer = 0
Dim pixelTotal As Integer = 0
Dim destinationValue As Byte = 0
Dim pixelValue As Integer = 128
Dim height As Integer = source.Height
Dim width As Integer = source.Width
Dim threshold As Integer = 500
' Iterate lines
For y As Integer = 0 To height - 1
sourceIndex = y * sourceData.Stride
destinationIndex = y * destinationData.Stride
destinationValue = 0
pixelValue = 128
' Iterate pixels
For x As Integer = 0 To width - 1
' Compute pixel brightness (i.e. total of Red, Green, and Blue values) - Thanks murx
' B G R
pixelTotal = Convert.ToInt32(sourceBuffer(sourceIndex)) + Convert.ToInt32(sourceBuffer(sourceIndex + 1)) + Convert.ToInt32(sourceBuffer(sourceIndex + 2))
If pixelTotal > threshold Then
destinationValue += CByte(pixelValue)
End If
If pixelValue = 1 Then
destinationBuffer(destinationIndex) = destinationValue
destinationIndex += 1
destinationValue = 0
pixelValue = 128
Else
pixelValue >>= 1
End If
sourceIndex += 4
Next
If pixelValue <> 128 Then
destinationBuffer(destinationIndex) = destinationValue
End If
Next
' Copy binary image data to destination bitmap
Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize)
' Unlock destination bitmap
destination.UnlockBits(destinationData)
' Dispose of source if not originally supplied bitmap
If Not source.Equals(original) Then
source.Dispose()
End If
'destination.SetResolution(300, 300)
' Return
Return destination
End Function
Private Function CreateStampImage(ByVal sMyStampName As String, ByVal iMaxWidth As Integer) As Bitmap
Dim MyImage As Bitmap = Nothing
Dim sN As String = Nothing
Dim sT As String = Nothing
Dim iFS As Integer = 0
Dim sF As String = Nothing
Dim bB As Boolean = False
Dim bI As Boolean = False
Dim bU As Boolean = False
Dim bS As Boolean = False
Dim iBW As Integer = 0
Dim iHP As Integer = 0
Dim iVP As Integer = 0
' Get stamp
Dim DynamicStamp As StampInfo = Stamp.GetInfo(StampIDbyName(sMyStampName), RASession)
' Add stamp properties to XML Document for parsing
Dim xd As New Xml.XmlDocument
If Not String.IsNullOrEmpty(DynamicStamp.CustomData) Then
xd.LoadXml(DynamicStamp.CustomData)
' Get XML Element with stamp properties
Dim xe As Xml.XmlElement = xd.DocumentElement
' Get xml Atributes from xml element
Dim Attribs As Xml.XmlAttributeCollection = xe.Attributes
' Process xml attributes
For Each Attrib As Xml.XmlAttribute In Attribs
Select Case Attrib.Name
Case "N" ' Get Stamp Name
sN = Attrib.Value
Case "T" ' Get Stamp text
sT = Attrib.Value
Case "FS" ' Get Font Size
iFS = Integer.Parse(Attrib.Value)
Case "F" ' Get Font Name
sF = Attrib.Value
If String.IsNullOrEmpty(sF) Then sF = "Arial"
Case "B" ' Get Bold
bB = Boolean.Parse(Attrib.Value)
Case "I" ' Get Italic
bI = Boolean.Parse(Attrib.Value)
Case "U" ' Get Underline
bU = Boolean.Parse(Attrib.Value)
Case "S" ' Get Strikethrough
bS = Boolean.Parse(Attrib.Value)
Case "BW" ' Get Boarder Width
iBW = Integer.Parse(Attrib.Value)
Case "HP" ' Get Horizontal Padding
iHP = Integer.Parse(Attrib.Value)
Case "VP" ' Get Vertical Padding
iVP = Integer.Parse(Attrib.Value)
End Select
Next
Dim myStyle As New FontStyle
If bB Then myStyle = myStyle Or FontStyle.Bold
If bI Then myStyle = myStyle Or FontStyle.Italic
If bU Then myStyle = myStyle Or FontStyle.Underline
If bS Then myStyle = myStyle Or FontStyle.Strikeout
Dim ImageList As New List(Of Bitmap)()
Dim iMaxW As Integer = iMaxWidth - (iHP + iHP) - (iBW + iBW)
Dim txtStamp As New List(Of String)
Dim sStampT As String = ReplaceStampTokens(sT)
' Replace new line syntax for splitting
sStampT = sStampT.Replace("\n", "�")
' Split Stamp text into individual lines
txtStamp.AddRange(sStampT.Split("�"))
For Each LineText As String In txtStamp
ImageList.Add(Convert_Text_to_Image(LineText, sF, myStyle, iFS, iMaxW))
Next
Dim iStampH As Integer = 0
Dim iStampW As Integer = 0
For Each bmp As Bitmap In ImageList
iStampH = iStampH + bmp.Height
If bmp.Width > iStampW Then
iStampW = bmp.Width
End If
Next
iStampH = iStampH + (iHP * 2) + (iBW * 2)
iStampW = iStampW + (iVP * 2) + (iBW * 2)
Dim iWritableHeight As Integer = iStampH - (iHP * 2) - (iBW * 2)
Dim iOffset As Integer = 0
MyImage = New Bitmap(iStampW, iStampH)
'MyImage.SetResolution(300, 300)
Dim MyGraphics As Graphics = Graphics.FromImage(MyImage)
If iBW > 0 Then
'draw a Black rectangle for boarder
MyGraphics.FillRectangle(New SolidBrush(Color.Black), 0, 0, MyImage.Width, MyImage.Height)
'draw a white rectangle inside the boarder
MyGraphics.FillRectangle(New SolidBrush(Color.White), iBW, iBW, MyImage.Width - (iBW * 2), MyImage.Height - (iBW * 2))
iOffset = iBW
Else
'draw a white rectangle
MyGraphics.FillRectangle(New SolidBrush(Color.White), 0, 0, MyImage.Width, MyImage.Height)
End If
For Each textImage As Bitmap In ImageList
If iWritableHeight >= ((iOffset + textImage.Height) - iBW) Then
MyImage = Superimpose(MyImage, textImage, iOffset, (iVP + iBW))
iOffset = iOffset + textImage.Height
End If
Next
MyImage = ConvertToBitonal(MyImage)
End If
Return MyImage
End Function
End Class
End Namespace
Use the fScale variable to scale the size of the stamp image on the page. fScale of 1.0 is no scaling, less than 1.0 shrinks the stamp on the page and greater than 1.0 grows the stamp on the page.