iTextSharp Добавление цвета фона к тексту водяного знака - PullRequest
0 голосов
/ 29 декабря 2011

Я добавляю текст водяного знака в PDF-файлы в созданной мной библиотеке классов. Код, который я разместил ниже, работает нормально, однако водяной знак иногда трудно прочитать, потому что он накладывается на контент в PDF. Как бы я добавил белый цвет фона вокруг текста водяного знака? Я бы хотел, чтобы текст водяного знака был заключен в белый прямоугольник размером с текст. Спасибо

Public Function AddWatermarkText(ByVal tempDirectory As String) As String
    ' Just return the full path of the PDF if we don't need to add a watermark.
    If Me.Document.RevRank <> 0 OrElse Me.Document.ReleaseDate Is Nothing Then Return Me.FullPath

    Dim reader As iTextSharp.text.pdf.PdfReader = Nothing
    Dim stamper As iTextSharp.text.pdf.PdfStamper = Nothing
    Dim gstate As New iTextSharp.text.pdf.PdfGState()
    Dim overContent As iTextSharp.text.pdf.PdfContentByte = Nothing
    Dim rect As iTextSharp.text.Rectangle = Nothing
    Dim watermarkFont As iTextSharp.text.pdf.BaseFont = Nothing
    Dim folderGuid As Guid = Guid.NewGuid()
    Dim outputFile As String = tempDirectory & System.IO.Path.DirectorySeparatorChar & folderGuid.ToString() & System.IO.Path.DirectorySeparatorChar _
                               & Me.Document.Prefix & Me.Document.BaseNumber & Me.Document.Revision & ".pdf"

    ' Create the temp directory to place the new PDF in.
    If Not My.Computer.FileSystem.DirectoryExists(tempDirectory) Then My.Computer.FileSystem.CreateDirectory(tempDirectory)
    My.Computer.FileSystem.CreateDirectory(tempDirectory & System.IO.Path.DirectorySeparatorChar & folderGuid.ToString())

    reader = New iTextSharp.text.pdf.PdfReader(Me.FullPath)
    rect = reader.GetPageSizeWithRotation(1)
    stamper = New iTextSharp.text.pdf.PdfStamper(reader, New System.IO.FileStream(outputFile, IO.FileMode.Create))
    watermarkFont = iTextSharp.text.pdf.BaseFont.CreateFont(iTextSharp.text.pdf.BaseFont.HELVETICA_BOLD, _
                                                  iTextSharp.text.pdf.BaseFont.CP1252, _
                                                  iTextSharp.text.pdf.BaseFont.NOT_EMBEDDED)
    gstate.FillOpacity = 0.9F
    gstate.StrokeOpacity = 1.0F

    ' Add the watermark to each page in the document.
    For i As Integer = 1 To reader.NumberOfPages()
        overContent = stamper.GetOverContent(i)
        With overContent
            .SaveState()
            .SetGState(gstate)
            .SetColorFill(iTextSharp.text.BaseColor.BLUE)
            .Fill()
            .BeginText()
            .SetFontAndSize(watermarkFont, 8)
            .SetTextMatrix(30, 30)

            If Me.Document.RevRank = 0 AndAlso Me.Document.ReleaseDate IsNot Nothing Then
                .ShowTextAligned(iTextSharp.text.Element.ALIGN_LEFT, UCase(String.Format("CONTROLLED DOCUMENT – THIS COPY IS THE LATEST REVISION AS OF {0}" _
                                                                                         , Date.Now.ToString("ddMMMyyyy"))), 10, rect.Height - 15, 0)
            End If

            .Fill()
            .EndText()
            .RestoreState()
        End With
    Next

    stamper.Close()
    reader.Close()

    Return outputFile
End Function

1 Ответ

1 голос
/ 05 января 2012

Мне обычно нравится иметь код, который вы можете просто набрать, но, к сожалению, ваш код слишком специфичен для домена, чтобы дать прямой ответ (много Me.*, о которых мы должны догадаться), но я все еще могу Вы получите небольшой рефакторинг кода.

Чтобы сделать то, что вы хотите, вы должны измерить строку, которую вы рисуете, а затем нарисовать прямоугольник с этими размерами. В спецификации PDF нет понятия «цвет фона» для текста, и любая реализация, которая делает его похожим, просто рисует прямоугольники для вас. (Да, вы можете выделить текст, но это аннотация, которая отличается.)

Итак, сначала я собираюсь вывести вещи в переменные, чтобы мы могли использовать их повторно и упростить их настройку:

''//Text to measure and draw
Dim myText As String = UCase(String.Format("CONTROLLED DOCUMENT – THIS COPY IS THE LATEST REVISION AS OF {0}", Date.Now.ToString("ddMMMyyyy")))
''//Font size to measure and draw with
Dim TextFontSize As Integer = 8
''//Original X,Y positions that we were drawing the text at
Dim TextX As Single = 10
Dim TextY As Single = rect.Height - 15

Далее нам нужно вычислить ширину и высоту. Первое легко, но второе требует, чтобы мы сначала получили текст «Восхождение и спуск», а затем вычислили разницу.

''//Calculate the width
Dim TextWidth As Single = watermarkFont.GetWidthPoint(myText, TextFontSize)
''//Calculate the ascent and decent
Dim TextAscent As Single = watermarkFont.GetAscentPoint(myText, TextFontSize)
Dim TextDescent As Single = watermarkFont.GetDescentPoint(myText, TextFontSize)
''//The height is the difference between the two
Dim TextHeight As Single = TextAscent - TextDescent

(ПРИМЕЧАНИЕ. Я не уверен, что GetWidthPoint(), GetAscentPoint() и GetDescentPoint() работают с многострочным текстом как требуется.)

Тогда вы, вероятно, захотите добавить отступ между полем и текстом:

''//Amount of padding around the text when drawing the box
Dim TextPadding As Single = 2

Наконец, где-то перед настройкой и рисованием текста вы хотите сначала нарисовать прямоугольник:

''//Set a background color
.SetColorFill(BaseColor.YELLOW)
''//Create a rectangle
.Rectangle(TextX - TextPadding, TextY - TextPadding, TextWidth + (TextPadding * 2), TextHeight + (TextPadding * 2))
''//Fill it
.Fill()
...